结构体对齐问题以及强制类型转换问题总结

本文详细介绍了内存对齐的概念、作用、原因,以及结构体对齐的原则,包括数据成员按数据类型自身对齐、结构体内部最大对齐值对齐等。同时讨论了使用#pragma pack宏对对齐的影响,并通过实例解析了结构体强制类型转换的注意事项,揭示了转换过程中可能遇到的不确定值问题。
摘要由CSDN通过智能技术生成

一、什么是对齐

    现在使用的计算机中内存空间都是按照字节划分的,从理论上讲似乎对任何类型的变量的访问都可以从任何地址开始,但实际上计算机系统对于基本数据类型在内存中的存放位置都有限制。举个例子,一个变量占用n个字节,则该变量的起始地址必须能够被n整除,即存放起始地址%n = 0。各种基本数据结构类型在内存中是按照这种规则排列,而不是一个紧接着一个排列的。这就是内存对齐。

    对结构体而言,存储的起始地址必须能被其成员中的数据类型占空间的值最大的那个整除。


二、对齐的作用和原因

    内存对齐作为一种强制的要求,第一简化了处理器与内存之间传输系统的设计,第二可以提升读取数据的速度。 各个硬件平台对存储空间的处理有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。 


三、对齐的原则

    在不使用#pragma pack宏的情况下,结构体的对齐原则有如下几个:

   原则一、数据成员按数据类型自身的对齐值对齐:结构的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始。

   原则二、结构体中有某些结构体成员,则结构体成员要按自身结构体内部最大对齐值进行对齐。一个简单的例子:struct A中包含struct B类型的成员,B中有char、int、double元素,那么B应该从sizeof(double)的整数倍开始存储。

   原则三、结构体的自身对齐值是其成员中自身对齐值最大的那个值。即结构体的总大小,必须是其内部最大成员的整数倍,不足的要补齐。

    下面通过几个例子,加深对这几个原则的理解:(32位系统,gcc编译器)

struct A{
  int a1;
  int a2;
};
struct B{
  char b1;
  int b2;
};
struct C{
  short c1;
  char c2;
  long c3;
};
struct D{
  short d1;
  long d2;
  char d3;
};
struct E{
  char e1;
  struct C e2;
  short e3;
};

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值