C++ 中struct,class及union 内存空间分配

本文详细解析了C++中结构体、联合体的内存分配原则,特别关注了内存对齐规则及其对不同成员组合的影响,并通过代码实例展示了如何计算这些复杂结构体的大小。

简述:

测试下在struct, class以及union分配内存大小时候会出现的问题


1.class ,struct部分

首先看一段代码, 猜测下输出是多少


#include <iostream>
using namespace std;

union Data0{
	char a[9];
	double b;
};

union Data1{
	Data0 a;
	char b;
};

struct Data2{
	Data0 a;
	char b;
};

int main() {
	cout << "sizeof Data0 " << sizeof(Data0) << endl;
	cout << "sizeof Data1 " << sizeof(Data1) << endl;
	cout << "sizeof Data2 " << sizeof(Data1) << endl;

	return 0;
}


这里有三个结构体Data0, Data1, 和Data2

我们都知道一个int是4个Byte , 一个double是8个Byte, 一个char是一个Byte大小

显然可以推测Data1这个结构体的大小是2 x 4 = 8 个Byte大小


但是, 如果我们认为Data2的大小是4 + 8 = 12的话那就错了!!

因为 :结构体的总大小,也就是sizeof的结果,. 必须是其内部最大成员的"最宽基本类型成员"的整数倍.不足的要补齐.(基本类型不包括struct/class/uinon)

所以double和int如果都在一个结构体里,那么int将被自动分配空间为8个Byte(尽管他本身只占4个Byte)

所以Data2的size是8 + 8 = 16


同理,Data3中多出来的那个char 虽然本身只需要8 + 1个Byte, 但是本着内存对齐原则, 多出来的那个char将自动补为8位 所以结果式8 + 8 + 8 = 24

struct输出:



2 .union部分

首先union的内存分配原则,是不同于struct的累加方式的, union本身只保留一块地址空间,因为只有一个成员真正存储于该地址, 但这块地址也要满足内存对齐原则

看这段代码,猜测下结果:

#include <iostream>
using namespace std;

union Data0{
	int a;
	int b;
};

union Data1{
	double a;
	int b;
};

union Data2{
	char a[9];
	double b;
};

int main() {
	cout << "sizeof union Data0 " << sizeof(Data0) << endl;
	cout << "sizeof union Data1 " << sizeof(Data1) << endl;
	cout << "sizeof union Data2 " << sizeof(Data2) << endl;
	return 0;
}

由于每次只保留一个基本变量的空间,所以Data0 可以猜到,只保留一个int的空间是4个Byte

然后看Data1 由于选取最大的单个基本变量空间,所以选取double 为8个Byte

Data2中, 最大单个基本变量是char数组为9个Byte,但是因为有double存在,因为要内存对齐,所以多余的那1个char自动转为 8 Byte的地址空间

所以,这个Data2的union大小为8 + 8 = 16

union输出:



3. Union Struct 混合部分

代码:


#include <iostream>
using namespace std;

union Data0{
	char a[9];
	double b;
};

union Data1{
	//use the smallest length Data0 : 16
	Data0 a;
	char b;
};

struct Data2{
	//the smallest length is double : 8 byte
	Data0 a;
	char b;
};

int main() {
	cout << "sizeof Data0 " << sizeof(Data0) << endl;
	cout << "sizeof Data1 " << sizeof(Data1) << endl;
	cout << "sizeof Data2 " << sizeof(Data2) << endl;

	return 0;
}

把Union对象Data0封装到Data1, 和Data2中,

在分配空间的时候,会类似拆分Data1 和Data2中的union对象,原则还是如上面两种, 不过如果成员是union,那么即使外面试struct遵循的方式还是Union


输出:



评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值