国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C > 正文

解析C語言中結構體struct的對齊問題

2020-01-26 14:38:41
字體:
來源:轉載
供稿:網友

首先看一下結構體對齊的三個概念值:

數據類型的默認對齊值(自身對齊):
1.基本數據類型:為指定平臺上基本類型的長度。如在32位機器中,char對齊值為1,short為2,int,float為4,double為8;
結構體:其數據成員中默認對齊值最大的那個值。
2.指定對齊值:#pragma pack (value)時的指定對齊值value。
3.數據類型的有效對齊值:默認對齊值和指定對齊值中小的那個值。
有了這些值,我們就可以很方便的來討論具體數據結構的成員和其自身的對齊方式。有效對齊值N是最終用來決定數據存放地址方式的值,最重要。有效對齊N,就是表示“對齊在N上”,也就是說該數據的“偏移量%N=0”。而數據結構中的數據變量都是按定義的先后順序來排放的。第一個數據變量的起始地址就是數據結構的起始地址。結構體的成員變量要對齊排放(對于非對齊成員需要在其前面填充一些字節,保證其在對齊位置上),結構體本身也要根據自身的有效對齊值圓整(就是結構體總長度需要是結構體有效對齊值的整數倍)。

通過上面的分析,對結構體進行字節對齊,我們需要知道四個值:

  • 指定對齊值:代碼中指定的對齊值,記為packLen;
  • 默認對齊值:結構體中每個數據成員及結構體本身都有默認對齊值,記為defaultLen;
  • 成員偏移量:即相對于結構體起始位置的長度,記為offset;
  • 成員長度:結構體中每個數據成員的長度(注結構體成員為補齊之后的長度),記為memberLen。

及兩個規則:

1.對齊規則:
offset % vaildLen = 0,其中vaildLen為有效對齊值vaildLen = min(packLen, defaultLen);

2.填充規則:
如成員變量不遵守對齊規則,則需要對其補齊;在其前面填充一些字節保證該成員對齊。需填充的字節數記為padLen:

padLen = getPadLen(offset , defaultLen);int getPadLen(int offsetLen, int defaultLen){  int vaildLen = min(packLen,defaultLen);  if(0 == vaildLen || 0 == offsetLen % vaildLen)  {    return 0;  }  return vaildLen - (offsetLen % vaildLen);}

結構體對齊算法思想:深度優先填充

先對齊內層結構體;
對每個數據成員計算其defaultLen、memberLen和offset;

再遍歷每個數據成員時計算;
對于基本數據類型成員defaultLen=memberLen;對于結構體成員defaultLen等于它的所有成員的最大的memberLen;
遍歷時對成員的memberLen進行累加,得到當前成員的offsetLen;
運用對齊及填充規則:在當前結構體成員前填充padLen個字節;


舉例說明:

struct{ short a; short b; short c; }A; sizeof(A) = 6; 

(vc6與gcc相同)

struct{ long a; short c; }A; sizeof(A) = 8;

(vc6與gcc相同), 它的內存分配為: a1 a2 a3 a4 , c1 c2 x x(a1為a的第一個字節,x為補齊字節,下同)

struct{int a;char b;short c; }A;sizeof(A) = 8;

A的內存分配為:

 a1 a2 a3 a4, b1 x c1 c2
struct{char a;int b;short c; }A1;sizeof(A1) = 12;

(vc6與gcc相同)

A1的內存分配為:

a1 x x x, b1 b2 b3 b4, c1 c2 x x

下面是更復雜的情況,結構體作為成員

struct{int a;doubl b;short c; }A; // sizeof(A) = 24 (vc6與gcc相同)struct{  char a,b;int c;double d;short e;struct A h;}B;sizeof(B) = 48 //(vc6與gcc相同)

A的內存分布:

a1 a2 a3 a4 x x x x, b1 b2 b3 b4 b5 b6 b7 b7, c1 c2 x x x x x x

B的內存分布:

a1 b1 x x, c1 c2 c3 c4 , d1 d2 d3 d4 d5 d6 d7 d8, e1 e2 x x x x 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 冕宁县| 彝良县| 凤山县| 河池市| 蕲春县| 新平| 万宁市| 安义县| 涞源县| 镇雄县| 华阴市| 深水埗区| 射阳县| 荆州市| 安阳市| 永善县| 大新县| 新河县| 喜德县| 十堰市| 二连浩特市| 凤冈县| 阿巴嘎旗| 越西县| 宽城| 开江县| 延边| 郎溪县| 津市市| 南部县| 朝阳县| 吉安市| 珠海市| 弥勒县| 莒南县| 山阴县| 玛多县| 池州市| 静乐县| 荥经县| 安陆市|