C++中类与结构体所占内存分析

本文探讨了C++中类和结构体的内存分配规则,通过实例展示了成员变量在内存中的布局。尽管某些成员变量按其实际大小分配空间,但系统会为了内存对齐而调整分配,导致类占用的总内存可能会超过预期。这种内存对齐策略旨在优化数据存取效率,避免因边界对齐问题造成的性能损失。
摘要由CSDN通过智能技术生成

  我们知道C++中不同类型数据占不同字节的,具体见下表:

数据类型32位64位
char11
int44
float48
double88

那么对于一个结构体或类占多少字节呢?

我们首先定义一个类:

class people
{
public:
	int  age_p;
	double weight_p;
	char name[5];
};

        机灵的小伙伴可能一口说出这个类所占的字节为4(int)+8(double)+5(char)=17。结果真的是这样吗?我们先创建这个类的一个对象p2 再sizeof(p2)获得该对象所占内存。

	people p2;
	cout<<"p2内存大小:"<<sizeof(p2)<<endl;

结果为:

         意外的是结果是24,那么到底是什么原因造成这样的结果呢?我们不妨将这个类中每个成员变量的地址与内存均显示出来,再进行分析。这里显示的地址为了直观性我选用了十进制地址显示的转换函数ip2decimal(),具体函数代码见:“C++显示十进制内存地址”。

	people p2;
	cout<<"p2地址:"<<ip2decimal(&p2)<<endl;
	cout<<"p2内存大小:"<<sizeof(p2)<<endl;

	cout<<"p2.age_p地址:"<<ip2decimal(&p2.age_p)<<endl;
	cout<<"p2.age_p内存大小:"<<sizeof(p2.age_p)<<endl;


	cout<<"p2.weight_p地址:"<<ip2decimal(&p2.weight_p)<<endl;
	cout<<"p2.weight_p内存大小:"<<sizeof(p2.weight_p)<<endl;

	cout<<"p2.name地址"<<ip2decimal(&p2.name)<<endl;
	cout<<"p2.name内存大小"<<sizeof(p2.name)<<endl;

结果为:

         由此可见虽然在person类中int型的age_p只需要4个字节,但系统给他分配了8个字节,double型分配了原本所需的8个字节,char虽需要5个字节但系统也给分配了8个字节,因此person实际的存储结构为:

         由此可知系统在为类分配内存空间时,如果类中某个对象所需空间最多为2^x,那么类中其它类型成员变量都会按照2^x的标准被系统分配空间。

        这种内存分配模式貌似会造成内存的浪费,实则不然,系统会根据不同对象的大小动态调节存储,我们再来看一个例子,首先定义一下它的类:

class data
{
public:
	int  num1;
	int  num2;
	int  num3;
	char str1[4];
	double num_double;
	char str2[5];
};
data p;

它的类与成员变量的地址与内存大小分别为:

由此可知类data的存储结构为: 

 到这里我们可以得出结论:

        对于一个类,系统会根据类中所需空间的最大的成员变量创建2^x大小的子空间,然后将类中成员变量依次往里放,当子空间满了或者子空间剩余空间无法放入下一个成员变量时,就会创建新的一个子空间,循环往复,直到所有的成员变量都放入到子空间中,最终的类的空间大小应该为子空间内存大小的整数倍。

对于结构体存储结构与类一致,感兴趣的可以自行实验。本文中如有表述错误的地方欢迎指正交流。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值