C++结构体成员内存对齐详细分析教程

C++内存对齐规则

预备知识

C++基本数据类型的字节数

在这里插入图片描述

注意:Windows系统32位和64位,同一基本类型数据占用字节一致。Linux下涉及到long类型则有所区别。

接下来测试一下64位 long类型所占字节大小

Windows下

          测试代码            测试结果        figure { display: inline-block; } 在这里插入图片描述

Linux下
在这里插入图片描述
在这里插入图片描述

1 默认对齐规则

  1. 默认按结构体中数据成员所占最大字节对齐。
  2. 按照声明顺序分配内存
  3. 数据成员变量的起始地址必须是该自身所占字节大小的整数倍。
  4. 结构体的大小必须是数据成员所占字节最大的整数倍,不够的补空白字节。
#include <iostream>
using namespace std;

struct A{
	char c1;
	char c2;
	int val;
};

struct B{
	char c1;
	int val;
	char c2;	
};

int main(){
	A a;
	cout<<"A的结构体大小:"<<sizeof(a)<<endl;   //测试结果:8
	B b;
	cout<<"B的结构体大小:"<<sizeof(b)<<endl;   //测试结果:12
	return 0;
}

分析一下结构体A结果:
在这里插入图片描述

S1:根据第一条规则,默认对齐方式是最大成员变量,所以按照4字节对齐。如上图每个格子代表一个字节,每四个一组。

S2:根据第二条规则,按照声明顺序分配内存,首先先考虑C1,在考虑C2,最后考虑val。

S3:根据第三条规则,(为方便讲述,默认位置为0,因为0一定是结构体得整数倍),C1占1个字节,放置第1个位置即可,

C2占1个字节,放第2个位置即可,(向这种占1个字节得可以放任意位置,因为每个地址都是1的整数倍),val占4个字节,不能放在2和3位置,因为2,3不是4的整数倍,所以空着,从下一行4开始放。

最后,从上图我们可以看出,结构体A占用8个字节。

结构体B的数据成员内存分配图如下。

在这里插入图片描述

分析过程同上:由上图可以,结构体B占用12个字节。

2 指定对齐规则

  1. 通过#pragma pack(num)指定结构体按照num字节对齐

    其中num = 1,2,4,8,…, 2 n 2^n 2n

  2. 结构体按照数据成员所占最大字节和指定字节中最小的那个对齐。即min(指定的字节,默认的字节对齐)

  3. 按照声明顺序分配内存。

  4. 数据成员变量的起始地址必须是该min(指定的字节,自身所占字节大小)的整数倍。

  5. 结构体的大小必须是min(指定的字节,默认的字节对齐)的整数倍,不够的补空白字节。

#include <iostream>
using namespace std;
#pragma pack(2)
struct A{
	char c1;
	char c2;
	int val;
};

struct B{
	char c1;
	int val;
	char c2;	
};
#pragma pop()

int main(){
	A a;
	cout<<"A的结构体大小:"<<sizeof(a)<<endl;   //测试结果:6
	B b;
	cout<<"B的结构体大小:"<<sizeof(b)<<endl;   //测试结果:8
	return 0;
}

结构体A的成员放置位置图如下,分析过程同上

在这里插入图片描述

结构体A的成员放置位置图如下,分析过程同上

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值