内存对齐(字节对齐、结构体对齐)
搜索:“内存对齐”、“字节对齐”、“结构体对齐”
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 是在变量的前面(高地址)补齐
补充:软件开发 , C++ ,