结构体数据对齐原则的一些补充
来源:互联网 发布:原油软件 编辑:程序博客网 时间:2024/05/21 21:45
数据对齐基本原则请看上一篇博客,这里针对结构体嵌套以及结构体含有static变量的情况做一些补充:
举个例子:
一、对于node3,含有静态数据成员
typedef struct node3{ int a; short b; static int c;}S3;
则sizeof(S3)=8.这里结构体中包含静态数据成员,而静态数据成员的存放位置与结构体实例的存储地址无关(注意只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的)。其在内存中存储方式如下:
|--------int--------| 4字节
|--short-|----|----| 4字节
而变量c是单独存放在静态数据区的,因此用siezof计算其大小时没有将c所占的空间计算进来。
二、再看结构体嵌套的情况:typedef struct node1{ int a; char b; short c;}S1;
typedef struct node5{ bool a; S1 s1; double b; int c;}S5;sizeof(S5)=32。
对于变量a,其自身对齐参数为1,#pragma pack(n)为8,则a的最终对齐参数为1,为它分配1字节的空间,它相对于结构体起始地址的偏移量为0,能被1整除;
对于s1,它的自身对齐参数为4(对于结构体变量,它的自身对齐参数为它里面各个变量最终对齐参数的最大值),#pragma pack(n)为8,所以s1的最终对齐参数为4,接下来的地址相对于结构体起始地址的偏移量为1,不能被4整除,所以需要在a后面填充3字节达到4,为其分配8字节的空间;(这里不能把s1看作整体,其大小为8,所以认为对齐参数为8,结构体嵌套的情况要把结构体“打散”来看对齐参数)
对于变量b,它的自身对齐参数为8,#pragma pack(n)的默认值为8,则b的最终对齐参数为8,接下来的地址相对于结构体起始地址的偏移量为12,不能被8整除,所以需要在s1后面填充4字节达到16,再为b分配8字节的空间;
对于变量c,它的自身对齐参数为4,#pragma pack(n)的默认值为8,则c的最终对齐参数为4,接下来相对于结构体其实地址的偏移量为24,能够被4整除,所以直接为c分配4字节的空间。
此时结构体所占字节数为1+3+8+4+8+4=28字节。
对于整个结构体来说,各个变量的最终对齐参数为1,4,8,4,最大值为8,#pragma pack(n)默认值为8,所以最终结构体的大小必须是8的倍数,因此需要在最后面填充4字节达到32字节。其存储如下:
|--------bool--------| 4字节
|---------s1---------| 8字节
|--------------------| 4字节
|--------double------| 8字节
|----int----|---------| 8字节
另外可以显示地在程序中使用#pragma pack(n)来设置系统默认的对齐参数,在显示设置之后,则以设置的值作为标准,其它的和上面所讲的类似,就不再赘述了,读者可以自行上机试验一下。如果需要取消设置,可以用#pragma pack()来取消。
再看一个例子:
struct A
{
short a1;
short a2;
short a3;
}A1;
struct B
{
char* a1;
char buf[5];
}B1;
struct C
{
B a;
A a2;
}C1;
sizeof(C)=20
前面说的结构体嵌套要“打散”,并不是说把C变成这样
struct C
{
char* a1;
char buf[5];
short a1;
short a2;
short a3;
}C1;
然后sizeof(C)=16=4+5+1(填充)+2+2+2。
“打散”是为了找最大对齐字节数。
首先a的起始地址为0,a作为结构体,为其分配的大小为12,这时候把a2“打散”,求最大对齐字节数为sizeof(short)=2,12能整除2,所以a2的起始地址为12,再给a2分配6个字节内存,这样总共有12+6=18个字节,对于整个结构体C来说,各个变量的最终对齐参数为4,1,2,2,2,最大值为4,所以最终结构体的大小必须是4的倍数,因此需要在最后面填充2字节达到20字节。
其存储如下:
|------char*--------| 4字节
|------char[5]------| 5字节
|-------------------| 3字节
|--------short------| 2字节
|--------short------| 2字节
|--------short------| 2字节
|----------| 2字节
- 结构体数据对齐原则的一些补充
- 结构体数据存储时的对齐原则
- 结构对齐的原则
- C语言结构体的对齐原则
- C语言结构体的对齐原则
- C语言结构体的对齐原则
- C语言结构体的对齐原则
- C语言结构体的对齐原则
- 结构体的数据对齐
- 彻底搞清计算结构体大小和数据对齐原则
- 彻底搞清计算结构体大小和数据对齐原则
- 结构体字节对齐原则
- 结构体字节对齐原则
- C语言结构体的字节对齐原则
- C语言结构体的字节对齐原则
- C语言结构体的字节对齐原则
- C语言结构体的字节对齐原则
- C语言结构体的字节对齐原则
- 做项目是抢,做互联网是拼。 一个是跟对手抢,一个是自己跟自己比拼。
- Multiple methods named 'count:' found with mismatched result, parameter type or attributes
- tp5分页样式整理
- 代码重构(四):条件表达式重构规则
- javaSE_8系列博客——Java语言的特性(二)--高级语言的基础知识(2)-- 变量和常用数据类型
- 结构体数据对齐原则的一些补充
- 算法-二叉树的前中后遍历stack版
- jupyter网站的使用以及常见linux下的简单的命令
- Unity Occlusion Culling 遮挡剔除研究
- 如何向IPython Notebook中导入.py文件
- 代码重构(五):继承关系重构规则
- the Undefined function 'caffe_' for input arguments of type 'char' 解决办法
- 虚拟机NAT模式无法上网问题的解决办法
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句