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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • scrapy start_urls_renpy中文文档

    scrapy start_urls_renpy中文文档#-*-coding:utf-8-*-importscrapyclassRenrenSpider(scrapy.Spider):name=’renren’allowed_domains=[‘renren.com’]#修改起始的请求start_urls=[‘http://www.renren.com/PLo…

    2022年7月28日
    4
  • 《linux 内核全然剖析》 chapter 2 微型计算机组成结构

    《linux 内核全然剖析》 chapter 2 微型计算机组成结构

    2021年11月16日
    41
  • excel多列合并关联数据[通俗易懂]

    excel多列合并关联数据[通俗易懂]假设现在有三张表第一张第二张第三张姓名与操作id相对应,现在想弄出这样的一个表,将多列数据整合起来那怎么做呢?需要用到函数vlookup这个查找值是合并时不变的那列,在这个案例下,就是指日期+姓名+操作id这三列,但是这里是不能写这么多的,只能是一列的第一个值,作为查找值,应该是像主键一样具有唯一的id。第一步,将三列合并为一列,需要用到函数concatenate公式

    2022年7月17日
    13
  • 程序员该不该去外包公司_程序员项目外包

    程序员该不该去外包公司_程序员项目外包最近,关于“外包”的话题,在程序员之间讨论得十分热烈。究竟什么叫外包呢?在IT行业,有些程序员在大公司的办公楼里,跟正式员工们一起工作。但是,他们并不隶属于这家公司,而是属于第三方公司,比如博彦科技,比如文思海辉,比如中软国际……这些人就像是后妈的孩子,他们的薪酬远不如大公司的正式工,上升空间也有限。他们有个共同的名字,叫做外包人员。那么,年轻的程序员们该不该进入…

    2022年9月30日
    0
  • Cocos2d-x 水果忍者划痕效果

    Cocos2d-x 水果忍者划痕效果

    2021年11月14日
    38
  • awk数组详解、实战

    awk数组详解、实战1.其它编程语言数组的下标一般从0开始,awk中数组下标默认从1开始,也可以从0开始设置:2.在awk中,元素的值设置为"空字符串"是合法的,所以不能用元素值是否为空,判断该元素

    2022年7月3日
    30

发表回复

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

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