缺省情况下,编译器默认将结构体、栈中的成员数据进行内存对齐。
编译器将未对齐的成员向后移,将每一个都成员对齐到自然边界上,从而也导致了整个结构的尺寸变大。
我们经常会接触到结构体,合理的设置结构体成员能做到节约内存的目的。
例子1:
#include <stdio.h>
struct test1
{
char a;
short b;
char c;
int i;
};
struct test2
{
char a;
char c;
short b;
int i;
};
int main()
{
printf("结构体大小test1:%d\n",sizeof(struct test1) );
printf("结构体大小test2:%d\n",sizeof(struct test2) );
getch();//窗口保留函数,调试使用
}
输出结果:
字节对齐规则:
字节对齐的规则是结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空。
字节。
test1的内存布局:
- 第一个char占一个字节,字节按1字节对齐。
- 第二个short占两个字节,字节变为2字节对齐,即使后面的变量是char也按照2字节存储。
- 第三个char占一个字节,字节也按2个字节对齐。
- 第四个int占四个字节,字节变为按4个字节对齐。
所以最后内存按照4个字节对齐
test2的内存布局:
- 第一个char占一个字节,字节按1字节对齐。
- 第二个char占一个字节,字节按1个字节对齐。
- 第三个short占两个字节,字节变为2字节对齐。
- 第四个int占四个字节,字节变为按4个字节对齐。
所以最后内存按照4个字节对齐
test2的1、2、3刚好凑够4个字节,按4字节对齐的话刚好是8字节。
看一个综合的例子:
#include <stdio.h>
union package
{
char head;
int body;
};
struct message
{
char id;
int crc;
union package pack;
long long i;
};
int main()
{
printf("结构体size=%d\n",sizeof(struct message));
getch();//窗口保留函数,调试使用
return 0;
}
输出结果:
通过分析可以知道内存从第二个成员开始按照4字节对齐,最后按照8个字节对齐。
注意:联合体(union)是按照联合体内存最大的那个成员来存储的。
本例子中联合体内最大为int,所以该联合体占4个字节。
所以内存布局为:
id为char占一个字节,crc为int占四个字节,现在已经占了5个字节了,放不下下一个字节了,内存对齐;union联合体开始第从第二个8字节地址储存;long long占8个字节,从第三个8字节地址储存。所以占了24个字节。