九九热这里直有精品,1区二区三区在线播放,玖玖爱在线观看资源,国产aⅴ综合网,午夜福利男女,日本亚洲欧美三级,日韩无码黄色导航,内射少妇13区,中文字幕高清网

您身邊的軟件定制專家--9年開發(fā)經(jīng)驗(yàn)為您護(hù)航

18678812288
0531-88887250

C++ 內(nèi)存對齊-濟(jì)南軟件開發(fā)

文章作者:濟(jì)南軟件開發(fā) 時(shí)間:2016年11月08日

  注:本文代碼測試環(huán)境為win7 X64 cpu, 編譯器為gcc4.7.1 和 vs2010

  內(nèi)存對齊是編譯器為了便于CPU快速訪問而采用的一項(xiàng)技術(shù)

  我們先從一個(gè)例子開始,對下面的類(或者結(jié)構(gòu)體)

  class node

  {

  char c;

  int i;

  short s;

  }no;

  sizeof(no)的值是多少呢,如果你的回答是7(1+4+2),那么你應(yīng)該認(rèn)真閱讀下面的內(nèi)容??梢栽诰幾g器上試試,輸出的結(jié)果是12,這就是內(nèi)存對齊的結(jié)果。

  為什么要進(jìn)行內(nèi)存對齊呢?

  平臺原因(移植原因):不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。

  性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對齊。原因在于,為了訪問未對齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對齊的內(nèi)存訪問僅需要一次訪問。                                                                       本文地址

  編譯器一般按照幾個(gè)字節(jié)對齊呢?本文中兩個(gè)編譯器默認(rèn)按照類中最大類型長度來對齊,我么也可以使用語句#pragma pack(i)(i = 1,2,4,8,16)來設(shè)置對齊字節(jié)數(shù)目,vs還可以在項(xiàng)目屬性-配置屬性-c/c++-代碼生成-結(jié)構(gòu)成員對齊設(shè)置。

  對齊規(guī)則如下:

  如果設(shè)置了內(nèi)存對齊為 i 字節(jié),類中最大成員對齊字節(jié)數(shù)為j,那么整體對齊字節(jié)n = min(i, j)  (某個(gè)成員的對齊字節(jié)數(shù)定義:如果該成員是c++自帶類型如int、char、double等,那么其對齊字節(jié)數(shù)=該類型在內(nèi)存中所占的字節(jié)數(shù);如果該成員是自定義類型如某個(gè)class或者struct,那個(gè)它的對齊字節(jié)數(shù) = 該類型內(nèi)最大的成員對齊字節(jié)數(shù)《詳見實(shí)例4》)

  每個(gè)成員對齊規(guī)則:類中第一個(gè)數(shù)據(jù)成員放在offset為0的位置;對于其他的數(shù)據(jù)成員(假設(shè)該數(shù)據(jù)成員對齊字節(jié)數(shù)為k),他們放置的起始位置offset應(yīng)該是 min(k, n) 的整數(shù)倍

  整體對齊規(guī)則:最后整個(gè)類的大小應(yīng)該是n的整數(shù)倍

  當(dāng)設(shè)置的對齊字節(jié)數(shù)大于類中最大成員對齊字節(jié)數(shù)時(shí),這個(gè)設(shè)置實(shí)際上不產(chǎn)生任何效果(實(shí)例2);當(dāng)設(shè)置對齊字節(jié)數(shù)為1時(shí),類的大小就是簡單的把所有成員大小相加

  我們通過以下幾個(gè)實(shí)例來分析

  實(shí)例1:(沒有指定對齊字節(jié),則n = 最大成員(int i)的大小4)

  class node

  {

  char c;   //放在位置0,位置區(qū)間[0]

  int i;      //4 = n, 那么放置起始位置應(yīng)該是4的倍數(shù),即4,位置區(qū)間為[4~7]

  short s; //2 < n,那么放置起始位置應(yīng)該是2的倍數(shù),即8,位置區(qū)間為[8~9]

  }

  此時(shí)成員共占用[0~9]10個(gè)字節(jié),還要整體對齊,大小應(yīng)該是4的倍數(shù),即12

  實(shí)例2:(假設(shè)指定對齊字節(jié)為8,那么n = min(8,4) = 4)

  class node

  {

  int i; //放在位置0,位置區(qū)間[0~3]

  char c; //1 < n, 那么放置起始位置應(yīng)該是1的倍數(shù),即4,位置區(qū)間為[4]

  short s; //2 < n,那么放置起始位置應(yīng)該是2的倍數(shù),即6,位置區(qū)間為[6~7]

  }

  成員共占據(jù)[0~7]8個(gè)字節(jié),剛好是4的倍數(shù),因此大小是8

  實(shí)例3:(假設(shè)指定對齊字節(jié)是2,則n = min(2,4) = 2)

  class node

  {

  char c; //放在位置0,位置區(qū)間[0]

  int i; //4 > n, 那么放置起始位置應(yīng)該是2的倍數(shù),即2,位置區(qū)間為[2~5]

  short s; //2 = n,那么放置起始位置應(yīng)該是2的倍數(shù),即6,位置區(qū)間為[6~7]

  }

  此時(shí)成員共占用[0~7]8個(gè)字節(jié),剛好是4的倍數(shù),因此大小是8

  實(shí)例4:(按照默認(rèn)設(shè)置)

  class temp

  {

  char c;

  int i;

  short s1;

  };

  由實(shí)例1可知,默認(rèn)對齊情況下,temp的大小是12,temp的對齊字節(jié)數(shù)是:三個(gè)成員取最大的,即為4;

  對于node,n = 其三個(gè)成員對齊字節(jié)數(shù)取最大,即等于t的對齊字節(jié)數(shù),也就是 4。

  class node

  {

  char c; //放在位置0,位置區(qū)間[0]

  temp t; //4(temp的對齊字節(jié)數(shù)) = n, 那么放置起始位置應(yīng)該是4的倍數(shù),即4,位置區(qū)間為[4~15]

  short s; //2 < n,那么放置起始位置應(yīng)該是2的倍數(shù),即16,位置區(qū)間為[16~17]

  }

  此時(shí)成員共占用[0~17]18個(gè)字節(jié),還要整體對齊,大小應(yīng)該是4的倍數(shù),因此大小是20

  實(shí)例5:(默然設(shè)置)

  對于node,n = 其三個(gè)成員對齊字節(jié)數(shù)取最大,即等于d的對齊字節(jié)數(shù),也就是 8。

  class node

  {

  temp t; //放在位置0,位置區(qū)間[0~11]

  double d; //8(temp的對齊字節(jié)數(shù)) = n, 那么放置起始位置應(yīng)該是8的倍數(shù),即16,位置區(qū)間為[16~23]

  short s; //2 < n,那么放置起始位置應(yīng)該是2的倍數(shù),即24,位置區(qū)間為[24~25]

  }

  此時(shí)成員共占用[0~25]26個(gè)字節(jié),還要整體對齊,大小應(yīng)該是8的倍數(shù),因此大小是32.

  類繼承時(shí)的內(nèi)存對齊

  考慮如下類

  class A

  {

  int i;

  char c1;

  }

  class B:public A

  {

  char c2;

  }

  class C:public B

  {

  char c3;

  }

  sizeof(C)結(jié)果是多少呢,gcc和vs給出了不同的結(jié)果,分別是8、16

  gcc中:C相當(dāng)于把所有成員i、c1、c2、c3當(dāng)作是在一個(gè)class內(nèi)部,(先繼承后對齊)

  vs中:對于A,對齊后其大小是8;對于B,c2加上對齊后的A的大小是9,對齊后就是12;對于C,c3加上對齊后的B大小是13,再對齊就是16 (先對齊后繼承)


想要了解更多詳情歡迎來電咨詢18678812288
登陸網(wǎng)址:m.h6244.cn。
聯(lián)系人:王經(jīng)理。

蒙自县| 阜阳市| 友谊县| 万山特区| 东乡族自治县| 荆州市| 高邮市| 龙井市| 平凉市| 淅川县| 苍南县| 体育| 错那县| 汝南县| 城固县| 萍乡市| 哈密市| 二连浩特市| 宁明县| 宣武区| 隆回县| 博乐市| 中超| 甘德县| 手游| 长垣县| 彭阳县| 兴仁县| 磴口县| 商河县| 岳阳县| 凤阳县| 天台县| 游戏| 汉中市| 长武县| 岑溪市| 温州市| 盐源县| 台湾省| 太谷县|