结构体字节对齐
程序员文章站
2024-02-23 20:18:46
...
#include <stdio.h>
typedef struct bb
{
int id;
double weight;
float height;
}BB;
typedef struct aa
{
char name[2];
int id;
short score;
short grade;
BB b;
}AA;
int main()
{
BB testb;
AA testa;
printf("%d, %d,%d,%d\n",sizeof(testb),sizeof(testb.id),sizeof(testb.weight),sizeof(testb.height));
printf("%d, %d,%d,%d,%d,%d\n",sizeof(testa),sizeof(testa.name),sizeof(testa.id),sizeof(testa.score),sizeof(testa.grade),sizeof(testa.b));
return 0;
}
原则一:
结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始(以结构体变量首地址为0计算)。
原则二:
在经过第一原则分析后,检查计算出的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。
原则三:
如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储.)
输出结果:
内存结构图
所有的C/C++编译器在排列数组的单元时,总是把各个数组单元存放在连续的存储区里,单元和单元之间没有空隙。但在存放结构对象的各个成员时,在某种编译环境下,可能会需要字对齐或双字对齐或者是别的什么对齐,需要在相邻两个成员之间加若干个"填充字节",这就导致各个成员之间可能会有若干个字节的空隙。
struct MyStruct
{
char a;
short b;
int c;
};
struct MyStruct ss={1,2,3};
//声明了结构对象ss,并把ss 的成员初始化为1 2和3。
struct MyStruct *ptr=&ss;
//声明了一个指向结构对象ss 的指针。它的类型是
//MyStruct *,它指向的类型是MyStruct。
int *pstr=(int*)&ss;
//声明了一个指向结构对象ss 的指针。但是pstr 和
//它被指向的类型ptr 是不同的。
printf("%x,%x,%x",*pstr,*pstr+1,*pstr+2);
输出结果:
020001,3,越界