C语言结构体对齐问题详解

转载自:http://blog.csdn.net/tiany524/article/details/6295551

测试环境32位机 WinXP:

编译器VC6(MS cl.exe ) 和 mingw32-gcc-4.5.2

1 结构体数据对齐(没有#pragma pack()宏定义)

结构体对齐可以总结为三个基本原则

①数据成员对齐规则:

结构体的数据成员中,第一个成员从offset为0的地址开始,以后每一个成员存储的起始位置为该成员大小的整数倍(在win32中int为32bit也即4字节对齐)

②结构体作为成员:

如果一个结构体1作为另一个结构体2的数据成员,则在结构体2中结构体1要从1内部成员最大的整数倍地址开始存储。

③结构体的总大小(sizeof):

为该结构体内部最大基本类型的整数倍,不足的要补齐,而不是简单的所有成员的大小总和。

举例说明

struct{

short a;

short b;

short c; }A; sizeof(A) = 6;(vc6与gcc相同)

struct{

long a;

short c; }A; sizeof(A) = 8;(vc6与gcc相同),根据原则③

它的内存分配为: a1 a2 a3 a4 , c1 c2 x x(a1为a的第一个字节,x为补齐字节,下同)

struct{

int a;

char b;

short c; }A;

sizeof(A) = 8;

A的内存分配为: a1 a2 a3 a4, b1 x c1 c2(原则1)

struct{

char a;

int b;

short c; }A1;

sizeof(A1) = 12; (vc6与gcc相同)

A1的内存分配为: a1 x x x, b1 b2 b3 b4, c1 c2 x x

下面是更复杂的情况,结构体作为成员

struct{

int a;

doubl b;

short c; }A; // sizeof(A) = 24 (vc6与gcc相同)

struct{

char a,b;

int c;

double d;

short e;

struct A h;

}B;

sizeof(B) = 48 //(vc6与gcc相同)

A的内存分布: a1 a2 a3 a4 x x x x, b1 b2 b3 b4 b5 b6 b7 b7, c1 c2 x x x x x x

B的内存分布:a1 b1 x x, c1 c2 c3 c4 , d1 d2 d3 d4 d5 d6 d7 d8, e1 e2 x x x x, A的分布

2 加入#pragma pack()宏定义)

#pragma pack(1)

上面的AB大小分别为14,30,对应于AB的内存分布,去掉x。

pack(2)时为14,30

pack(4)时为16,36

3 结构体的位域

结构体中引入位于是为了压缩存储空间。而且位于成员不能单独计算sizeof。

位域大致有5条基本规则。

① 如果相邻字段的类型相同,且位宽之和小于该类型的sizeof(), 则可以紧邻着前一个字段存储,直到不能在容纳位置;

struct{

char a:2;

char b:4;

char c:5; }A; // sizeof(A) = 2

内存分布: a1 a2 x x, b1 b2 b3 b4, c1 c2 c3 c4 c5 x x x,这里每一个代表一个bit,与上一节不同

struct{

int a:2;

int b:3;

int c:3; }A; // sizeof(A) = 4, 参照后面的原则5

②如果相邻字段的类型相同,但是位宽之和大于该类型的sizeof(), 则后面的字段将从新的存储单元开始存储,且offset为其类型大小的整数倍;

struct{

char a:6;

char b:3;

char c:3; }A; // sizeof(A) = 2

struct{

int a:20;

int b:20;

int c:3; }A; // sizeof(A) = 8, 同时参照后面的原则5

③如果相邻位域字段类型不同,各编译器的处理不同,VC6不压缩,GCC压缩。

struct{

int a:4;

char b:1;

int c:3; }A;

sizeof(A) = 12, VC6

sizeof(A) = 4, gcc, 压缩了为什么不是3? 同时参照后面的原则5

④如果位域字段之间插入非位域字段,各编译器的处理不同

struct{

int a:4;

char b;

int c:3; }A;

sizeof(A) = 12, VC6

sizeof(A) = 4, gcc, a1 a2 a3 a4 x x x x ,b1~b8, c1 c2 c3 x x x x x

struct{

char a:4;

char b;

char c:3; }A;

sizeof(A) = 3, VC6

sizeof(A) = 3, gcc,

⑤整个结构体的总大小为其最宽基本类型的整数倍。

转载于:https://www.cnblogs.com/Sunlnx/p/3366678.html

c/c++ 编译器内存对齐问题相关推荐

  1. C++笔记——有关内存对齐

    32位编译器: char :1个字节 char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节.同理64位编译器) short int : 2个字节 int: ...

  2. Eigen向量化内存对齐/Eigen的SSE兼容,内存分配/EIGEN_MAKE_ALIGNED_OPERATOR_NEW

    1.总结 对于基本数据类型和自定义类型,我们需要用预编译指令来保证栈内存的对齐,用重写operator new的方式保证堆内存对齐.对于嵌套的自定义类型,申请栈内存时会自动保证其内部数据类型的对齐,而 ...

  3. nginx源码分析--内存对齐处理

    1.nginx内存对齐主要是做2件事情: 1) 内存池的内存地址对齐: 2) 长度按照2的幂取整.因为前面结构体已经是对齐了,如果后面的内存池每一小块不是2的幂,那么后面的就不能对齐 2.通用内存对齐 ...

  4. C++中的内存对齐介绍

    网上有很多介绍字节对齐或数据对齐或内存对齐的文章,虽然名字不一样,但是介绍的内容大致都是相同的.这里以内存对齐相称.注:以下内容主要来自网络. 内存对齐,通常也称为数据对齐,是计算机对数据类型合法地址 ...

  5. 内存对齐与ANSI C中struct型数据的内存布局 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-3032209.html 当在C中定义了一个结构类型时,它的大小是否等于各字段(field)大小之和?编译器将 ...

  6. 内存对齐/字节对齐/数据对齐/地址总线对齐

    其实是使用InitializeAcl()时发现有个aligned,可我不知道什么是aligned 于是乎我就先搜索了对齐,结果发现了一大堆,什么[字节对齐].[内存对齐].[地址总线 对齐].[数据对 ...

  7. 内存对齐的规则以及作用

    内存对齐能够用一句话来概括: "数据项仅仅能存储在地址是数据项大小的整数倍的内存位置上" 比如int类型占用4个字节.地址仅仅能在0,4.8等位置上. 由一个程序引入话题: //环 ...

  8. c语言20字节的内存的数据怎么读取_C++编程-内存对齐

    内存对齐可以大大提升内存访问速度,是一种用空间换时间的方法. 1.内存对齐的计算机原理 内存地址对齐,是一种在计算机内存中排列数据(表现为变量的地址).访问数据(表现为CPU读取数据)的一种方式,包含 ...

  9. C 语言编程 — 内存对齐

    目录 文章目录 目录 内存对齐 为什么要内存对齐? 内存对齐跟平台有关 对齐系数 使用 pragma 宏指令修改对齐系数 内存对齐的原则 内存对齐 计算机的内存空间都是按照字节划分的,元素(包括:变量 ...

最新文章

  1. [Medical Image Processing] 2. Image Binary -【OTSU Algorithm Entropy Method】
  2. redis在linux命令行下连续进行命令操作
  3. QComboBox 样式设置
  4. 微软Scott CIO也要代表公司拜访客户
  5. webpack4打包工具
  6. thumbnailator 一个好用的图像处理工具集
  7. 告别鼠标——【Windows下常见系统快捷键】
  8. 系统提示 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。
  9. 网站运维都需要做什么工作
  10. python分词原理_结巴分词原理
  11. 云联惠认证身份_在秘乐短视频上实名认证了,输入了手机号,身份证号码,姓名,人脸识别,会被网贷吗?...
  12. 【数学建模笔记 24】数学建模的时间序列模型
  13. java程序设计六大原则
  14. 手机端,跟pc 链接qq 客服
  15. 交通-地铁客流量python时间序列预测
  16. python控制结束多线程_python进阶八——并发编程之多线程
  17. Python按照指定的分隔符拆分字符串split()函数
  18. Power BI数据查询编辑
  19. JDBC Connection... will not be managed by Spring
  20. 以太网2出现两个ip地址-解决办法

热门文章

  1. 自己电脑访问跳板机里面的集群中的web ui界面
  2. oct玻璃体后脱离图像
  3. Please move ‘proctime(r_proctime)‘ to the end of the schema.以及rowtime和proctime
  4. flink的datastream输出没有结果
  5. xxx must either be declared abstract or implement abstract method ‘call(T1, T2)‘ in ‘Function2
  6. 对于多对多关系的对象,如何建表与关联查询(转载)
  7. OpenGL函数:wglCreateContext
  8. 深度学习(三)——Autoencoder, 词向量
  9. 一次经典的tcp三次握手
  10. Ueditor/自定义配置