struct的成员对齐
Intel、微軟等公司曾經出過一道類似的面試題:
#include <iostream.h>
#pragma pack(8)
struct example1
{
short a;
long b;
};
struct example2
{
char c;
example1 struct1;
short e;
};
#pragma pack()
int main(int argc, char* argv[])
{
example2 struct2;
cout << sizeof(example1) << endl;
cout << sizeof(example2) << endl;
cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;
return 0;
}
問程序的輸入結果是什么?
答案是:
8 16 4
不明白?還是不明白?下面一一道來:
?
1.1 自然對界struct 是一種復合數據類型,其構成元素既可以是基本數據類型(如int、long、float 等)的變量,也可以是一些復合數據類型(如array、struct、union 等)的數據單元。對于結構體,編譯器會自動進行成員變量的對齊,以提高運算效率。缺省情況下,編譯器為結構體的每個成員按其自然對界(natural alignment)條件分配空間。各個成員按照它們被聲明的順序在內存中順序存儲,第一個成員的地址和整個結構的地址相同。
? ? ? 自然對界(natural alignment)即默認對齊方式,是指按結構體的成員中size 最大的成員對齊。
例如:
struct naturalalign
{
char a;
short b;
char c;
};
? ? ? 在上述結構體中,size 最大的是short,其長度為2 字節,因而結構體中的char 成員a、c 都以2 為單位對齊,sizeof(naturalalign)的結果等于6;
如果改為:
struct naturalalign
{
char a;
int b;
char c;
};
其結果顯然為12。
1.2 指定對界一般地,可以通過下面的方法來改變缺省的對界條件:
· 使用偽指令#pragma pack (n),編譯器將按照n 個字節對齊;
· 使用偽指令#pragma pack (),取消自定義字節對齊方式。
? ? ? 注意:如果#pragma pack (n)中指定的n 大于結構體中最大成員的size,則其不起作用,結構體仍然按照size 最大的成員進行對界。
例如:
#pragma pack (n)
struct naturalalign
{
char a;
int b;
char c;
};
#pragma pack ()
? ? ? 當n 為4、8、16 時,其對齊方式均一樣,sizeof(naturalalign)的結果都等于12。而當n 為2時,其發揮了作用,使得sizeof(naturalalign)的結果為6。
? ? ? 在VC++ 6.0 編譯器中,我們可以指定其對界方式(見圖1),其操作方式為依次選擇projetct >setting > C/C++菜單,在struct member alignment 中指定你要的對界方式。
? ? ? 圖1 在VC++ 6.0 中指定對界方式
?
?
?
?
? ? ? 另外,通過__attribute((aligned (n)))也可以讓所作用的結構體成員對齊在n 字節邊界上,但是它較少被使用,因而不作詳細講解。
?
1.3 面試題的解答? ? ? 至此,我們可以對Intel、微軟的面試題進行全面的解答。程序中第2 行#pragma pack (8)雖然指定了對界為8,但是由于struct example1 中的成員最大size 為4(long 變量size 為4),故struct example1 仍然按4 字節對界,struct example1 的size為8,即第18 行的輸出結果;
struct example2 中包含了struct example1,其本身包含的簡單數據成員的最大size 為2(short變量e),但是因為其包含了struct example1,而struct example1 中的最大成員size 為4,structexample2 也應以4 對界,#pragma pack (8)中指定的對界對struct example2 也不起作用,故19 行的輸出結果為16;
? ? ? 由于struct example2 中的成員以4 為單位對界,故其char 變量c 后應補充3 個空,其后才是成員struct1 的內存空間,20 行的輸出結果為4。
?
vb6中字符串的內存分布
http://topic.csdn.net/u/20100305/10/2398150e-ae14-4456-93a8-6abeee6d2b96.html?1173930695
總結
以上是生活随笔為你收集整理的struct的成员对齐的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 枚举IHTMLDocument2中所有I
- 下一篇: 函数调用约定