c语言结构体对齐

今天遇到一个结构体没有对齐的问题,导致指向结构体的指针递增的时候,偏移出错。


struct x{

uint64 a;

uint16 b;

uint16 c;

uint32 d;

uint8  arr[4];

}

如果编译器选择8字节(Packs structures on 8-byte boundaries (default).)对齐,那么这个结构体的大小是多少呢?

答案是:8+2+2+4+4+4 = 24;


MSDN是这样说的:

When you specify this option, each structure member after the first is stored on either the size of the member type orn-byte boundaries (where n is 1, 2, 4, 8, or 16), whichever is smaller.

第一个成员之后的成员放置在min(自身大小,Zpn指定的大小)的边界上。


一开始以为是2个uint16造成的不对齐,实际上是struct结构体本身也需要对齐的原因,因为如果你分配一个数组(假设分配器第一个机构体放在8字节的边界上),这个结构体本身不是8字节对齐,那么,第二个元素的所有成员就不是按照预想的那样对齐了(不同于第一个元素)。


1, 所以结构体对齐,包含2个方面,一个成员的对齐,还有就是最后整个结构体的对齐。


2, 一般情况下设置对齐大小是实际机器大小的整数倍,一般就是一倍,也就是相等。


实例:

// compile with /Zp:4
struct x{
  int32 a;
  char  b;
  int16 c;
  char  arr[5]
}



### C语言结构体对齐的原理和实现方式 #### 一、结构体对齐的基本概念 在C语言中,为了提高数据访问效率以及满足硬件架构的要求,编译器会对结构体中的成员进行字节对齐处理。这种对齐遵循一定的规则,主要包括以下几个方面: 1. **第一个成员的位置** 结构体的第一个成员始终存储在其分配空间的起始地址上[^1]。 2. **其他成员的对齐规则** 其他成员会存储在一个称为“对齐数”的整数倍地址上。这个对齐数值取决于两个因素:一是该成员自身的大小;二是当前使用的编译器设置的默认对齐值。最终的实际对齐数是两者之间的较小值[^1]。 3. **不同平台下的差异** 编译器的不同可能导致对齐策略有所区别。例如,在Windows平台上使用Microsoft Visual Studio时,默认对齐数通常为8字节;而在Linux环境下GCC编译器则可能采用4字节作为默认对齐单位[^1]。 4. **整体大小调整** 整个结构体的总尺寸会被扩展到内部所有成员中最长对齐需求长度的一个整数倍。这意味着如果最后一个字段不需要额外填充来达到这一目标,则不会增加多余的空间消耗[^3]。 #### 二、具体实例分析 下面通过几个具体的代码片段进一步说明上述理论如何应用实践当中: ##### 示例1: 单纯字符型与整形组合情况 考虑以下简单定义: ```c #pragma pack(8) // 设置全局对齐参数为8字节 struct Example { char ch; int num; }; ``` 这里`ch`占据单个字节而`num`需要四个连续字节存放。由于我们指定了较大的打包指令(`pack=8`),所以即使只有这两个元素存在也至少得预留八位给整个对象[`sizeof(struct Example)`返回值应等于8][^2]. ##### 示例2: 复杂嵌套情形 再来看一段稍微复杂一点的例子涉及到了子结构体的情况: ```c #pragma pack(push, 8) typedef struct _s1{ short a; /* size = 2 */ long b; /* size = 4 or 8 depending on architecture*/ } S1; typedef struct _s2{ char c; /* size = 1 */ S1 d; /* contains 'a' and 'b', total aligned to max of them */ int e; /* size = 4 */ }s2; #pragma pack(pop) ``` 在这个场景里,S1类型的变量d本身又包含了多个属性因此它自己的布局也要考虑到各自的数据类型特性再加上外部施加的影响共同决定最后的结果即`s2`的整体规模应该是可以被最高级别也就是long或者double之类的大容量单元所接受的形式呈现出来[^4]. #### 三、总结 综上所述,C编程环境里的记录式复合数据形式——结构体会因为多种原因经历一系列复杂的排列过程从而形成特定模式下的物理表现形态这其中包括但不限于初始定位点选取原则、后续各项间间隔距离设定依据还有总体框架外围边界划定标准等等诸多环节相互作用最终达成既定目的同时兼顾性能优化考量. --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值