搜索:“內存對齊”、“字節對齊”、“結構體對齊”
Example-01:
[cpp]
#include <stdio.h>
typedef struct
{
int a;
char b;
int c;
} Test1;
typedef struct
{
char a;
int b;
char c;
} Test2;
typedef struct
{
int a;
char b[9];
int c;
} Test3;
int main()
{
Test1 t1;
Test2 t2;
Test3 t3;
int a;
char b;
char b2[9];
int c;
printf("Test1: %d\n", sizeof(Test1));
printf("Test1: %d\n", &t1);
printf("Test1.a: %d\n", &t1.a);
printf("Test1.b: %d\n", &t1.b);
printf("Test1.c: %d\n", &t1.c);
printf("Test2: %d\n", sizeof(Test2));
printf("Test2: %d\n", &t2);
printf("Test2.a: %d\n", &t2.a);
printf("Test2.b: %d\n", &t2.b);
printf("Test2.c: %d\n", &t2.c);
printf("Test3: %d\n", sizeof(Test3));
printf("Test3: %d\n", &t3);
printf("Test3.a: %d\n", &t3.a);
printf("Test3.b: %d\n", t3.b);
printf("Test3.c: %d\n", &t3.c);
printf("a: %d\n", &a);
printf("b: %d\n", &b);
printf("b2: %d\n", b2);
printf("c: %d\n", &c);
return 0;
}
/*
VC++ 6.0:
Test1: 12
Test1: 1245044
Test1.a: 1245044
Test1.b: 1245048
Test1.c: 1245052
Test2: 12
Test2: 1245032
Test2.a: 1245032
Test2.b: 1245036
Test2.c: 1245040
Test3: 20
Test3: 1245012
Test3.a: 1245012
Test3.b: 1245016
Test3.c: 1245028
a: 1245008
b: 1245004
b2: 1244992
c: 1244988
gcc:
Test1: 12
Test1: 2293572
Test1.a: 2293572
Test1.b: 2293576
Test1.c: 2293580
Test2: 12
Test2: 2293560
Test2.a: 2293560
Test2.b: 2293564
Test2.c: 2293568
Test3: 20
Test3: 2293540
Test3.a: 2293540
Test3.b: 2293544
Test3.c: 2293556
a: 2293536
b: 2293535
b2: 2293526
c: 2293520
*/
存儲布局圖如下:
Example-02(改編自《C陷阱與缺陷》4.4):
[cpp]
#include <stdio.h>
int main()
{
int i;
char c;
int j;
printf("i address:%d\n",&i);
printf("c address:%d\n",&c);
printf("j address:%d\n",&j);
for(i=0 ; i<5; i++)
{
scanf("%d",&c);
printf("%d ",i);
}
return 0;
}
/*
gcc:
i address:2293580
c address:2293579
j address:2293572
3
0 3
0 3
0 3
0 100000
390
VC++ 6.0:
i address:1245052
c address:1245048
j address:1245044
3
0 10000
1 3000
2 333333333333
3 333
4
*/
這段程序在用VC編譯運行時沒問題的,但是用gcc編譯運行是有問題的,原因是因為 i 的前3個字節的內存被 scanf() 輸入的整數的後三個字節覆蓋導致的,內存布局圖見上圖:
Example-01, Example-02 小結:
1、對於結構體裡面的成員變量的內存布局,gcc 和 VC 是相同的(如果不考慮 gcc 的優化),對於函數中緊挨著的變量,gcc 是在變量的後面(低地址)補齊,VC 是在變量的前面(高地址)補齊