下面结构体变量data占多少字节?
代码示例1
# include <stdio.h>
struct STUDENT
{
char a;
int b;
}data;
int main(void)
{
printf("%p, %p\n", &data.a, &data.b); //%p是取地址输出控制符
printf("%d\n", sizeof(data));
return 0;
}
输出结果
结果分析
输出并不是我们想象中的1+4 = 5字节,而是8字节。因为结构体中有一个字节对齐的概念。
什么叫字节对齐?
结构体是按字节对齐的方式存储成员变量的!即以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。
以上面程序为例,结构体变量data的成员中占内存最多的数据类型是int型,其占4字节的内存框架,那么所有成员在分配内存时都要与4字节的长度对齐。也就是所,虽然char只占1字节,但是为了与4字节的长度对齐,它后面的3字节都会空着(所谓空着其实也不是里面真的什么都没有),即:
示例代码2
# include <stdio.h>
struct STUDENT
{
char a;
char b;
int c;
}data;
int main(void)
{
printf("%p, %p, %p\n", &data.a, &data.b, &data.c); //%p是取地址输出控制符
printf("%d\n", sizeof(data));
return 0;
}
输出结果
结果分析
假如结构体中最大的数据类型在内存中占N字节,那么对齐的原则是:理论上所有成员在分配内存都是紧接在前一个变量后面依次填充的,但是如果是“以N对齐”为原则,那么如果一行中剩下的空间不足以填充某成员变量,即剩下的空间小于某成员变量的数据类型所占的字节数,则该成员变量在分配内存时另起一行分配。
示例代码3
# include <stdio.h>
struct STUDENT
{
char name[5];
int age;
char sex;
float score;
}data;
int main(void)
{
printf("%p,%p,%p,%p,%p\n%p\n%p\n%p\n", &data.name[0], &data.name[1], &data.name[2], &data.name[3], &data.name[4], &data.age, &data.sex, &data.score);
printf("%d\n", sizeof(data));
return 0;
}
运行结果
结果分析
char a[5]的本质是5个char变量,所以结构体变量data中成员最长类型占4字节,还是以4对齐。该结构体变量分配内存时情况如下: