關(guān)于內(nèi)存對齊的一點注解

一第练、內(nèi)存對齊的原因

大部分的參考資料都是如是說的:

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

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

二志秃、對齊規(guī)則

每個特定平臺上的編譯器都有自己的默認(rèn)“對齊系數(shù)”(也叫對齊模數(shù))怔球。比如32位系統(tǒng)默認(rèn)對齊系數(shù)是 4, 64位的則可以達到 8.

程序員可以通過預(yù)編譯命令

#pragma pack(n)  // n=1,2,4,8,16

來改變這一系數(shù)浮还,其中的n就是指定的“對齊系數(shù)”竟坛。

另外,可以通過GCC提供的 __attribute__ 擴展機制取消對齊優(yōu)化钧舌。

規(guī)則:

  1. 數(shù)據(jù)成員對齊規(guī)則:結(jié)構(gòu)(struct)或聯(lián)合(union)的數(shù)據(jù)成員担汤,第一個數(shù)據(jù)成員放在offset為0的地方,以后每個數(shù)據(jù)成員的對齊按照 #pragma pack 指定的數(shù)值和這個數(shù)據(jù)成員自身長度中洼冻,比較小的那個進行崭歧。

  2. 結(jié)構(gòu)(或聯(lián)合)的整體對齊規(guī)則:在數(shù)據(jù)成員完成各自對齊之后,結(jié)構(gòu)(或聯(lián)合)本身也要進行對齊撞牢,對齊將按照 #pragma pack 指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長度中率碾,比較小的那個進行叔营。

三、試驗

下面通過一例子的說明這個規(guī)則

編譯器:GCC4.6.3, (g++)

操作系統(tǒng):Ubuntu 12所宰, Windows 7

struct test {
  short a;
  double b;
  int c;
  char d;
};

在GCC中绒尊,各類型的大小如下:

sizeof(char)) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(float) = 4
sizeof(double) = 8
sizeof(long long) = 8

注解:在32位系統(tǒng),n=4

相當(dāng)于:

#pragma pack(4)
struct test {
  short a; // 按2字節(jié)對齊仔粥,存放區(qū)間:0-1
  double b; // 按4字節(jié)對齊婴谱,存放區(qū)間:4-11
  int c; // 按4字節(jié)對齊,存放區(qū)間:12-15
  char d; // 按1字節(jié)對齊件炉,存放區(qū)間:16
};
#pragma pack()

最后整體對齊勘究,按4圓整矮湘,故:

    sizeof(test) = 20

注解:在64位系統(tǒng)斟冕,默認(rèn)的對齊系數(shù)為8

struct test {
  short a; // 按2字節(jié)對齊,存放區(qū)間:0-1
  double b; // 按8字節(jié)對齊缅阳,存放區(qū)間:8-15
  int c; // 按4字節(jié)對齊磕蛇,存放區(qū)間:16-19
  char d; // 按1字節(jié)對齊,存放區(qū)間:20
};

最后整體對齊十办,按8圓整秀撇,故:

    sizeof(test) = 24

注解:C++允許在結(jié)構(gòu)體中定義static變量,靜態(tài)變量分配在同一的靜態(tài)存儲區(qū)向族,不包含在結(jié)構(gòu)體大小中呵燕。

如下:

#pragma pack(4)
struct test {
  short a;
  double b;
  int c;
  char d;
  static int d;
};
#pragma pack()

該結(jié)構(gòu)體的大小仍為 20.

在標(biāo)準(zhǔn)C,似乎并沒有這種用法件相。

【原文鏈接:http://mirreal.github.io/blog/2014/09/15/memory-alignment/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末再扭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子夜矗,更是在濱河造成了極大的恐慌泛范,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊撕,死亡現(xiàn)場離奇詭異罢荡,居然都是意外死亡,警方通過查閱死者的電腦和手機对扶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門区赵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浪南,你說我怎么就攤上這事惧笛。” “怎么了逞泄?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵患整,是天一觀的道長拜效。 經(jīng)常有香客問我,道長各谚,這世上最難降的妖魔是什么紧憾? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮昌渤,結(jié)果婚禮上赴穗,老公的妹妹穿的比我還像新娘。我一直安慰自己膀息,他們只是感情好般眉,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潜支,像睡著了一般甸赃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冗酿,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天埠对,我揣著相機與錄音,去河邊找鬼裁替。 笑死项玛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弱判。 我是一名探鬼主播襟沮,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昌腰!你這毒婦竟也來了开伏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤剥哑,失蹤者是張志新(化名)和其女友劉穎硅则,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體株婴,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡怎虫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了困介。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大审。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖座哩,靈堂內(nèi)的尸體忽然破棺而出徒扶,到底是詐尸還是另有隱情,我是刑警寧澤根穷,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布姜骡,位于F島的核電站导坟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏圈澈。R本人自食惡果不足惜惫周,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望康栈。 院中可真熱鬧递递,春花似錦、人聲如沸啥么。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悬荣。三九已至菠秒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間隅熙,已是汗流浹背稽煤。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工核芽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留囚戚,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓轧简,卻偏偏與公主長得像驰坊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子哮独,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,498評論 25 707
  • 通過一段代碼來描述內(nèi)存對齊的現(xiàn)象拳芙。 上述代碼打印出來的結(jié)果為:24,16 為什么相同的結(jié)構(gòu)體,只是交換了變量 ab...
    豆瓣菜閱讀 6,682評論 5 26
  • 簡單理解#pragma 作為較為復(fù)雜的預(yù)處理指令之一皮璧,它的作用為更改編譯器的編譯狀態(tài)以及為特定的編譯器提供特定的編...
    Umiade閱讀 1,964評論 0 0
  • hello.c Makefile 流程 :
    王一航閱讀 695評論 0 0
  • 張嘉佳說舟扎,每個人的記憶都是一座城,里面住著一個不可能的人悴务,那個人路過了青春一陣子睹限,但會在記憶里擱淺一輩子。 距離那...
    唐半仙閱讀 672評論 2 9