結構體的內存分配
假設這臺機器 sizeof(char) = 1 sizeof(int) = 4 sizeof(double) = 8
Struct中各個成員對齊遵循以下原則:
- 結構體每個成員相對于結構體首地址的偏移量(offset)都是(這個)成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節(internal adding)。
- 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之后加上填充字節(trailing padding)。
- 還有一個額外的條件:結構體變量的首地址能夠被其最寬基本類型成員的大小所整除。
4.對于結構體成員屬性中包含結構體變量的復合型結構體再確定最寬基本類型成員時,應當包括復合類型成員的子成員(子結構體的寬度為子結構體最大的成員)。但在確定復合類型成員的偏移位置時則是將復合類型作為整體看待。
例子1:
struct MyStruct {
int a; //4個字節
char b; //1個字節
int c; //4個字節
char d; //1個字節
}
sizeof(mystruct) = 16;
a:偏移0, 大小4, 0是4的整數倍; 分配4個字節
b: 偏移4, 大小1; 分配1個字節
c: 偏移5, 大小4,5不是3的整數倍所以需要在C的前面補3個字節; 分配3 + 4=7個字節
d: 偏移4+1+3+4=12,大小1; 分配12 + 1=13個字節
13不是4(最大成員的占用的字節數)的整數倍,所以需要在最后一個成員后面補3位。即總共分配 13 + 3 = 16字節
例子2:
struct MyStruct {
int a; //4個字節
char b; //1個字節
int c; //4個字節
char d; //1個字節
};
struct MyPreventStruct {
int a; //4個字節
char b; //1個字節
struct MyStruct myStruct;
};
sizeof(MyStruct) = 16; (見例子1)
sizeof(MyPreventStruct) = 24;
a:偏移0, 大小4, 0是4的整數倍; 分配4個字節
b: 偏移4, 大小1; 分配1個字節
myStruct: 偏移5, 大小16, 偏移5不是大小4(MyStruct中最寬的元素)的整數倍,所以需要在前面補3位。 分配 11+16=27個字節。
總大小=4 + 1 + 3 + 16 = 24;