Struct Align

基本介紹

C 以變數類型配置記憶體空間,常見類型及大小如下

1
2
3
4
5
6
7
8
9
char 	        1 byte 	        -128 to 127 or 0 to 255
unsigned char 1 byte 0 to 255
signed char 1 byte -128 to 127
int 2 or 4 bytes -32,768 to 32,767 or -2,147,483,648 to 2,147,483,647
unsigned int 2 or 4 bytes 0 to 65,535 or 0 to 4,294,967,295
short 2 bytes -32,768 to 32,767
unsigned short 2 bytes 0 to 65,535
long 4 bytes -2,147,483,648 to 2,147,483,647
unsigned long 4 bytes 0 to 4,294,967,295

32 bits 的架構上,一次的資料存取也就是32 bits (4bytes)

4 bytes 不是隨便從哪個點抓都可以,而是以4 bytes 為單位

比如說第 0,4,8 ,12….等,而不會是從3,7,9 開始

這表示了對齊 (alignment)的重要,因為會影響到幾次才抓的完。

如果要抓一個4 bytes 的int,而這個int是從 6 擺到 10,那就表示要抓兩次

因為會先 (4),5,6,7 再來 (8),9,10,11,範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
int main(int argc, char* argv[])
{
struct align_test
{
char x; // 1 byte
int y; // 4 byte
short int z; // 2 byte
};
struct align_test test;


printf("test size is %d\n", sizeof(test));
printf("x size is %d\n", sizeof(test.x));
printf("y size is %d\n", sizeof(test.y));
printf("z size is %d\n", sizeof(test.z));

printf("address of test is %p\n", &test);
printf("address of x is %p\n", &test.x);
printf("address of y is %p\n", &test.y);
printf("address of z is %p\n", &test.z);
return 0;
}

test size is 12
x size is 1
y size is 4
z size is 2

address of test is 0x7fffb6237f00
address of x is 0x7fffb6237f00
address of y is 0x7fffb6237f04
address of z is 0x7fffb6237f08


所以放的位址如下
+---+---+---+---+---+---+---+---+---+---+---+---+
| x | p | p | p | y | y | y | y | z | p | p | p |
+---+---+---+---+---+---+---+---+---+---+---+---+
0 1 2 3 4 5 6 7 8 9 10 11


照理說應該只要 1+4+2 = 7 byte 空間
但是因為 4 byte align 造成浪費,其中的 p 為 padding
所以實際上會變為

struct align_test
{
char x; // 1 byte
char padding0[3];
int y; // 4 bytes
short int z; // 2 bytes
char padding1[2];
};

如果不想浪費空間可以改為

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#pragma pack(push)      /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */
struct align_test
{
char x; // 1 byte
int y; // 4 bytes
short int z; // 2 bytes
};
#pragma pack(pop) /* restore original alignment from stack */

test size is 7
x size is 1
y size is 4
z size is 2
address of test is 0x7fff7230a290
address of x is 0x7fff7230a290
address of y is 0x7fff7230a291
address of z is 0x7fff7230a295


所以放的位址如下
+---+---+---+---+---+---+---+
| x | y | y | y | y | z | z |
+---+---+---+---+---+---+---+
0 1 2 3 4 5 6

參考

參考

參考