这个结构体是怎么为他分配内存的?
struct A{
int a;
char b;
char c;
long d;
};
理论上,int类型是4字节,char类型是1字节,long类型是8字节,总计14字节,但是答案是16字节。
先做个测试
printf("sizeof(A) = %ld\n",sizeof(struct A));
结果是 sizeof(A) = 16
为啥?
使用联合结构来测试一下,联合结构可以让多个变量共用一个内存区域,我们再定义一个占16位的结构,然后测试。
struct B{
char c1[16];
};
确定以下几个概念:
编译器是按照成员列表的顺序来为每个成员分配内存空间。
- 1.结构体的每个元素相对于结构体首地址的偏移量都是元素大小的整数倍,如有需要编译器会在元素之间加上填充字节。
例如结构{char a,double b}
分配按字节分配的则是 a 0 0 0 0 0 0 0 b b b b b b b b,因为b必须要满足关于首地址偏移是8的整数倍,共分配了16字节
- 2.结构体的总大小为结构体最宽基本类型元素大小的整数倍,如有需要编译器会在最末一个元素之后加上填充字节
例如结构{double a,char b}
分配按字节分配的则是 a a a a a a a a b 0 0 0 0 0 0 0,即使后面7个字节用不上,但是也被分配了。
- 3.如果结构体内存在长度大于处理器位数的元素,那么就以处理器的倍数为对齐单位;否则,如果结构体内的元素的长度都小于处理器的倍数的时候,便以结构体里面最长的数据元素为对齐单位。
代码测试
-
按照以上原则,我们认为struct A的分配方式是这样的,现在我们用代码测试一下
-
我们通过联合的方式,让struct A 和struct B公用一块内存,这样我们就能操作那几个用来占位的区域
-
首先通过struct B,让这个16字节的每个字节都 = 127 ,也就是char ch[i] = 127;
-
然后在再通过struct A ,对int double 赋0值。两个char 分配赋值 1 2
- 输出一下:
sizeof(A) = 16
sizeof(B) = 16
sizeof(A_B) = 16
0 0 0 0 1 2 127 127 0 0 0 0 0 0 0 0
- 显然没有问题了
全部代码
#include<stdio.h>
#define N 16
struct A{
int a;
char b;
char c;
double d;
};
struct B{
char c1[N];
};
union A_B{
struct A a;
struct B b;
};
int main() {
printf("sizeof(A) = %ld\n",sizeof(struct A));
printf("sizeof(B) = %ld\n",sizeof(struct B));
union A_B ab;
for(int i = 0 ; i < N ; i++){
ab.b.c1[i] = 127;
}
ab.a.a = 0;
ab.a.b = 1;
ab.a.c = 2;
ab.a.d = 0;
printf("sizeof(A_B) = %ld\n",sizeof(union A_B));
for(int i = 0 ; i < N ; i++){
printf("%d ",ab.b.c1[i]);
}
}