C++中类的内存对齐「建议收藏」

C++中类的内存对齐

大家好,又见面了,我是全栈君。

1.对于C++中的类的内存占用,存在一个很容易出现错误的点。就是:当一个类中并没有定义任何的成员变量也没有定义虚函数的时候,内存的占用情况,代码如下:

class MyClass
{ 
   
public:
	MyClass();
	~MyClass();
	//virtual void fun() {}; // 4

private:
	//int a; // 4
	//char b; // 1
	//double c; // 8
};

MyClass::MyClass()
{ 
   
}

MyClass::~MyClass()
{ 
   
}

int main()
{ 
   
	// test03
	std::cout << "size int :" << sizeof(int) << " size char:" << sizeof(char) << " size double:" << sizeof(double) << std::endl;
	std::cout << "size MyClass:" << sizeof(MyClass) << std::endl;
}

各位看官们,你们觉得结果会是如何呢?

没错,结果并不是0而是1,这个没有定义任何成员变量也没有定义任何的虚函数的类占用的是一个字节内容。

size int :4 size char:1  size double:8
size MyClass:1

那么只是为什么呢?
因为对于没有数据成员的对象,其内存单元也不是0,c++用一个内存单元来表示这个实例对象的存在

2.C++中的类的内存对齐方式,到底是以几个字节作为对齐标准呢?4个?8个?又或者是更多呢?代码如下,各位看官猜一猜吧。

class MyClass
{ 
   
public:
	MyClass();
	~MyClass();
	//virtual void fun() {}; // 4

private:
	int a;      // 4
	char b;     // 1
	//double c; // 8
};

MyClass::MyClass()
{ 
   
}

MyClass::~MyClass()
{ 
   
}

int main()
{ 
   
	// test03
	std::cout << "size int :" << sizeof(int) << " size char:" << sizeof(char) << " size double:" << sizeof(double) << std::endl;
	std::cout << "size MyClass:" << sizeof(MyClass) << std::endl;
}

输出如下:

size int :4 size char:1  size double:8
size MyClass:8

4个字节作为对齐?没错,在这个情况下是以4个字节作为对齐的,但是真的就是都是以4个字节作为内存对齐的标准的吗?其实并不是的,再看看下面的代码吧。

class MyClass
{ 
   
public:
	MyClass();
	~MyClass();
	//virtual void fun() {};

private:
	//int a; // 4
	char b;     // 1
	double c;    // 8
};

MyClass::MyClass()
{ 
   
}

MyClass::~MyClass()
{ 
   
}

int main()
{ 
   
	// test03
	std::cout << "size int :" << sizeof(int) << " size char:" << sizeof(char) << " size double:" << sizeof(double) << std::endl;
	std::cout << "size MyClass:" << sizeof(MyClass) << std::endl;
}

输出结果如下:

size int :4 size char:1  size double:8
size MyClass:16

这下懵逼了吧,现在的内存对齐的标准又变成了8个字节了,其实并不然。C++中的类的对齐的字节,并不是一个定数,而是以类中的成员变量占用的字节数最大的类型作为对齐标准的

3.同时还有一个极为容易忽略的占用内存类型(虚函数表),注意类有虚函数指针,别忘了虚函数指针还有4字节,代码如下:

class MyClass
{ 
   
public:
	MyClass();
	~MyClass();
	virtual void fun() { 
   };

private:
	//int a; // 4
	//char b; // 1
	//double c; // 8
};

MyClass::MyClass()
{ 
   
}

MyClass::~MyClass()
{ 
   
}

int main()
{ 
   
	// test03
	std::cout << "size int :" << sizeof(int) << " size char:" << sizeof(char) << " size double:" << sizeof(double) << std::endl;
	std::cout << "size MyClass:" << sizeof(MyClass) << std::endl;
}

输出结果会是多少呢?4?错了,并不是4,而是8.

size int :4 size char:1  size double:8
size MyClass:8

为什么占用8个字节呢?因为这个就和第一个易错点有联系了,因为现在这个类内部并没有定义有成员数据,c++用一个内存单元来表示这个实例对象的存在,这一个内存字节,因为存在虚函数表(4个字节),所以经过内存对齐之后,这个类所占用的内存大小就是8了,而不是4了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115091.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 十进制与八进制和十六进制之间的转换

    十进制与八进制和十六进制之间的转换

  • 一般人到底要不要学Python_Python值得学吗

    一般人到底要不要学Python_Python值得学吗前言本人纯屌丝一枚,在学python之前对电脑的认知也就只限于上个网,玩个办公软件。这里不能跑题,我为啥说自学python,一般人我还是劝你算了吧。因为我就是那个一般人。基础真的很简单,是个人稍微认点真都能懂,这就是好多人说的python简单、易懂、好学,然后就是一顿浮夸的言论,误导那些小白,再然后那些小白也就跟着浮夸。这里我就给那些轻浮的人泼一桶冷水,懂跟学会是一码事吗?先来说哈python这个就业哈,我现在生活在祖国的肚皮上–成都,(嗯,有想了解川西迷你小环线的在下面留言哦),下面亲身经历,我喃,

  • Java取余和取模

    Java取余和取模抛开高级语言的实现,取余运算和取模运算本身并不完全一致,区别在于对负整数进行取商时操作不同。虽然这样说,但是取余运算和取模运算的公式都一样。对于x和y两个整数(int),通过以下两个操作获取余数或模数:step1、求商:intz=x/ystep2、求余数或模数:intresult=x-y*z它们的差别在于,如果z的值…

  • java中的io流知识总结_java中的io流开发用的多吗

    java中的io流知识总结_java中的io流开发用的多吗通过前面的简单学习,我们已经能够大致了解了关于文件的操作,但是能够明显感受到在执行其他的操作的时候,还是会有一些不方便的地方存在,因此今天我们会学习另外四个IO流来帮助我们对文件进行操作,这四个流分别是缓冲流、转换流、序列化、打印流。好了,废话不多说,我直接开始今天的学习吧!……

    2022年10月20日
  • apache2虚拟主机实现一个服务器绑定多个域名[通俗易懂]

    apache2虚拟主机实现一个服务器绑定多个域名[通俗易懂]1.apache2的配置首先要配置好apache2,如果未配置,请参考我之前的博文:lamp的配置2.域名的解析将全部域名的www和@的A记录解析到云服务器的IP3.虚拟主机的配置1.配置httpd.conf如果etc/httpd/conf/httpd.conf存在,则配置此httpd.conf如果etc/httpd/conf/httpd.conf不存在,此时需要我们在/etc/apache2下

  • ADN中国队参加微软Kinect他赢得了全国比赛三等奖,我们的创意项目与团队Kinect于Naviswork虚拟之旅

    ADN中国队参加微软Kinect他赢得了全国比赛三等奖,我们的创意项目与团队Kinect于Naviswork虚拟之旅

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号