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


相关推荐

  • android之service简单介绍

    一 什么是Service二 如何使用Service 三 Service的生命周期  一 什么是Service Service,看名字就知道跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,也需要在配置文件里注册,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startServ

    2022年3月9日
    47
  • 程序员看过都说好的资源网站,你懂得![通俗易懂]

    程序员看过都说好的资源网站,你懂得![通俗易懂]身为一个程序员,有时候为了程序的界面好看,不得不去查找一些好看的图标或者图片等来装饰网站,那么问题来了,去哪里找?不用慌,程序羊为大家整理了一些常用的网站,希望能对您有帮助!后续还会不断更新。喜欢记得关注程序羊喔,不然下次您就找不到程序羊了。

    2022年6月10日
    83
  • 深度学习笔记(三):激活函数和损失函数

    深度学习笔记(三):激活函数和损失函数这一部分来探讨下激活函数和损失函数。在之前的logistic和神经网络中,激活函数是sigmoid,损失函数是平方函数。但是这并不是固定的。事实上,这两部分都有很多其他不错的选项,下面来一一讨论3.激活函数和损失函数3.1激活函数关于激活函数,首先要搞清楚的问题是,激活函数是什么,有什么用?不用激活函数可不可以?答案是不可以。激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么

    2022年7月14日
    16
  • select top 1 * from tablename[通俗易懂]

    select top 1 * from tablename[通俗易懂]今天在网上查找selecttop1*fromDepartMent的信息时,找到的信息答案不是很准确所以现在把自己的答案张贴出来。希望对大家有所帮助。selecttop1*fromtablename这段SQL语句的意思是:读取一个表中的第一条记录。如果是selecttop 5*fromtablename这样的话呢就是读取表中记录的前5条记录。  

    2022年7月15日
    17
  • worldpress怎么增加登录注册按钮

    worldpress怎么增加登录注册按钮1 首先登上你的 worldpress 后台 2 搜索 wechatsocial 安装在插件里点击启用 或安装 一路点击即可一直点蓝色的按钮即可其他的设置看你的需求了 3 开启注册按钮

    2025年9月15日
    3
  • preference用法for_interference用法

    preference用法for_interference用法文章目录PreferenceFragment简介PreferenceFragment使用PreferenceFragment扩展PreferenceFragment简介在我们写一个项目的时候,基本都有选项设置界面,这类设置界面的原理基本都是本地的一些个性化设置,通过读取本地设置来改变某些差异显示(例如字体大小,主题颜色,WIFI自动下载等)。这些设置一般都会使用Preference来保存,…

    2025年9月30日
    4

发表回复

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

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