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了。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 滑动窗口算法通用思想

    滑动窗口算法通用思想本文详解「滑动窗口」这种高级双指针技巧的算法框架,带你秒杀几道难度较大的子字符串匹配问题:最小覆盖子串找到字符串中所有字母异位词无重复字符的最长子串最后抽象出一个简单的滑动窗口算法框架。LeetCode上至少有9道题目可以用此方法高效解决。但是有几道是VIP题目,有几道题目虽不难但太复杂,所以本文只选择点赞最高,较为经典的,最能够讲明白的三道题来讲解。第一题为了让读者掌握算法模…

    2025年6月27日
    6
  • 数据挖掘——关联规则挖掘

    数据挖掘——关联规则挖掘《数据挖掘》国防科技大学《数据挖掘》青岛大学数据挖掘之关联规则挖掘关联规则挖掘(AssociationRuleMining)最早是由Agrawal等人提出。最初的动机是解决购物篮分析(BasketAnalysis)问题,目的是发现交易数据库(TransactionDatabase)中不同商品之间的联系规则。定义关联规则是描述在一个交易中物品之间同时出现的规律的知识模式,更确切的说,关联规则是通过量化的数字描述物品X的出现对物品Y的出现有多大的影响。关联分析associationana

    2022年7月17日
    18
  • fftw_fftw3

    fftw_fftw3http://wenku.baidu.com/link?url=3TS6UqnYfVxGpVBfJIIgxjjcXCKuW9NvklxfBLZaIdWJhY0HrpUSKyyuIHsNI2s4F9tSUOhP7pl7n5PLlSFvWqQdr6XvtpejqQenhJHJ9N7

    2025年8月19日
    5
  • java系统高并发解决方案(转载)[通俗易懂]

    java系统高并发解决方案(转载)[通俗易懂]转载博客地址:http://blog.csdn.net/zxl333/article/details/8454319一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术经过这些年的发展,已经细分到很细的方方面面,尤其对于大

    2022年5月31日
    28
  • Django(20)ORM模型迁移命令

    Django(20)ORM模型迁移命令迁移命令makemigrations:将模型生成迁移脚本。模型所在的app,必须放在settings.py中的INSTALLED_APPS中。这个命令有以下几个常用选项:app_label:后面可

    2022年7月28日
    10
  • HttpClient4模拟表单提交[通俗易懂]

    HttpClient4模拟表单提交[通俗易懂]这里用httpclient4.3模拟一个表单普通文本提交的方法建一个servlet接受表单数据,只传递2个参数,name和password//servlet的访问地址是:http://localhost:80/testjs/servlet/FormServletpublicclassFormServletextendsHttpServlet{publicvoidd

    2022年7月22日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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