结构体占用内存,如何计算

最近一直研究结构体占用内存空间大小问题,在网上看了很多文章,很多都是有问题的,所以自己总结了一份,已通过验证,如有问题,请多指教!

编译器环境:keil 5.0

语言:C


结构体占用空间计算要点:双管齐下

1、内部数据对齐

2、整个空间对齐


入题分析:

struct SIZE
{
double a;
int b;
char c;
double d;
};

先不考虑双管齐下计算SIZE数据占用空间,double 8个字节,int 4个字节, char 1个字节,所以一共占用8*2 + 4 + 1 = 21bits但计算机为了存储方便,对结构体数据进行补齐处理,如图所示,涂色部分为数据真正占用的空间,第3个数据char只占用1bit,但分配空间时,给分配了4bits,多余的3个bits就是为了给第四个数据对齐使用。

对齐算法:对齐主要看当前数据偏移量,偏移量首地址如果能除进数据占用空间大小即可表示为对齐,否则补齐处理。

第一个数据a首地址为0,数据位8bits,所以第二个数据首地址为8,可除进第二个数据int型4bits,8 / 4 = 2,所以无需对齐处理,同理,第三个数据也无需处理对齐问题,第四个数据double占用8 bits,首地址为13,不可除进8,所以需要对第三个数据进行对齐处理,13补到16即可除进8,所以第三个数据补3bits,第四个数据偏移量为16,所以整个数据空间为24 bits,符合双管齐下1。结构体内部最大数据double占用8 bits,数据整体占用24 bits,成倍数关系,所以符合双

### C++ 中结构体内存布局及计算规则 #### 结构体成员排列原则 编译器按照声明顺序依次分配空间给各个成员变量。对于不同类型的成员,会根据其自身的大小以及目标平台的字节对齐要求来决定实际占用的空间量[^1]。 #### 字节对齐机制 为了提高访问速度,在大多数情况下,CPU读取特定宽度的数据(如32位整数)时希望这些数据位于能够被该宽度整除的位置上。因此,当定义一个包含多种基本类型成员的复合对象(比如`struct`),如果不对它们做特殊处理,则可能会因为交错分布而导致效率低下甚至无法正常工作。为此引入了所谓的“填充字节”,即在某些成员之间插入额外的空白区域使得后续成员可以满足上述条件[^2]。 #### 默认最大边界值设定 通常来说,默认的最大边界取决于当前体系架构下指针所指向的对象所能表示的最大地址偏移量;而在具体实现层面则由编译工具链自行规定——例如GCC/Clang默认采用8作为64bit系统的标准单位长度[^3]。 #### 自定义调整指令 可以通过预处理器命令改变这一行为模式,像MSVC支持通过`#pragma pack(n)`指定新的打包因子n (其中 n=1,2,4,8 或者 16),从而影响到之后遇到的所有结构化实体直到遇见另一个相同形式但参数不同的语句为止[^4]。 #### 实际案例分析 考虑如下几个例子: ##### 示例A ```cpp typedef struct A { char c; int i; }; ``` 这里`char`1个字节而`int`通常是4个连续存储单元。由于后者需要按四倍间隔放置,所以在二者中间加入了三个无意义却必要的间隙字符以确保整体尺寸达到预期效果:最终得到的结果应该是5加上一次向上取整至最接近的四位数倍数处结束,也就是8字节。 ##### 示例B ```cpp typedef struct B { char c; int i; double d; }; ``` 同样地遵循前面提到的原则进行扩展操作后可知此实例中的总容量应为16字节。 ##### 示例C ```cpp typedef struct C { char c; int i; double d; char c1; }; ``` 此时除了维持原有逻辑外还需注意最后一个单字节项后面也会存在若干补充位置以便让整个记录符合双精度浮点型所需的八重定位需求,故而预测出来的总体积大约等于24字节。 ##### 特殊情况D 假设现在有这样一种情形: ```cpp #pragma pack(4) //修改默认对齐数为4 struct D { char a; double b; char c; }; ``` 即使设置了较小的整体约束力也无法阻止内部较大组件单独享有更宽松的标准,所以这里的输出将是12而非单纯依靠外部指示得出结论。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值