C++类的内存对齐

本文探讨了C++中的内存对齐现象,解释了编译器进行内存对齐的原因,包括平台移植需求和性能优化。内存对齐遵循特定的规则,如数据成员对齐和结构自身的对齐。通过实例分析了编译器如何调整变量在内存中的位置以满足对齐要求,从而节省内存并提高访问效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先来看一下内存对齐的例子

#include<iostream>
struct a1
{
	char c1;
	char c2;
	int n;
	double d;
};

struct a2
{
	char c1;
	int n;
	char c2;
	double d;
};
int main()
{
	std::cout<<sizeof(a1)<<std::endl<<sizeof(a2);
}

输出的结果为16和24,按照常规思想,char占一个字节,int占4个字节,double占8个字节,输出的结果应该都是 1 + 1 + 4 + 8 = 14 1+1+4+8=14 1+1+4+8=14,但是结果却不是这样!!这就是由于编译器让变量内存对齐的原因。
内存对齐

内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。引用自百度百科。

通俗的说就是对于结构体中的变量,编译器会开辟一段连续的存储空间,把变量都放在里面,然后编译器为了某些原因不会照顺序的分配内存给变量。对于第一个例子来说不会 0 ∣ 1 ∣ 2345 ∣ 678910111213 ∣ 0|1|2345|678910111213| 012345678910111213这样分配内存,编译器会改变变量在内存中的位置。这里补充一个知识,在main前声明的结构不占内存,在main里的结构定义计算机才分配内存。

这样做的原因
1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。引用自百度百科。

具体如何解释,我想学完编译原理再来补充。
内存对齐的规则

  • 数据成员的对齐
    偏移量:比如在结构体a1中,c1的偏移量为0,如果不做内存对齐c2的偏移量为1,n的偏移量为2。
    C语言还有一个#pragma pack(n)括号里为常量的编译预处理指令,如果不设置默认为8。对于每一个变量编译器会把它的偏移量设置为min(n, sizeof(这个变量))的整数倍,当然第一个放在偏移量为0位置。
    比如第一个例子
    c1放在0,c2放在1,对于n不对齐前,其偏移量为2很明显不是 m i n ( 8 , s i z e o f ( i n t ) ) = 4 min(8,sizeof(int))=4 min(8,sizeof(int))=4的倍数,所以编译其会把n右移到4这个位置, 3 , 4 3,4 34这两个位置就空出来了,对于d此时它的偏移量恰好为8是min…的倍数。所以最后总的内存是16。分配情况是 0 ∣ 123 ∣ 4567 ∣ 89101112131415 0|123|4567|89101112131415 0123456789101112131415
  • 结构本身的对齐
    在对齐完数据成员后,结构总的偏移量要为min(n,sizeof(结构中所占最大的变量))的倍数,如果不满足也要对齐。这里更前面差不多,可以自行去证明。
    最后这个规则对联合跟类也同样使用。注意类中一般还有成员函数,函数同样也要当作变量对齐,但是类中只有虚函数才在类中占据内存,其他不占。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值