关于结构体占用空间大小总结

本文详细探讨了C/C++中结构体变量占用内存的原理,包括字节对齐、数据类型的内存占用、#pragma pack指令的影响,以及结构体、联合体和枚举在内存中的布局。通过实例分析了不同对齐方式下结构体大小的计算方法,并强调了静态成员变量不占用结构体空间的特点。
摘要由CSDN通过智能技术生成

关于C/C++中结构体变量占用内存大小的问题,之前一直以为把这个问题搞清楚了,今天看到一道题,发现之前的想法完全是错误的。这道题是这样的:

在32位机器上,下面的代码中

class A
{
public:
	int i;	
	union U
	{
		char buff[13];
		int i;
	}u;		

	void foo(){}	
	typedef char* (*f)(void*);
	enum{red , green, blue}color;	
}a;


sizeof(a)的值是多少?如果在代码前面加上#pragma pack(2)呢?

我之前一直有的一个错误的观念是,编译器会将某些大小不足4字节的数据类型合并起来处理。虽然很多情况下效果也是这样的,但是,这样理解是没有把握到问题的本质,在某些情况下就会出错,比如带上#pragma pack(2)之后,那样的理解就没法分析了。

真实的情况是,数据占用内存的大小取决于数据本身的大小和其字节对齐方式,所谓对齐方式即数据在内存中存储地址的起始偏移应该满足的一个条件。比如说,一个int数据,在32位机上(以下的讨论都以此为基础)占用4个字节,如果该数据的偏移是0x00000003,那么CPU就要先取一个char,再取一个short,最后取一个char,三次取数据组合成一个int类型。(为什么不能取一次char,然后再取一个3字节长的数据呢?这个问题从组成原理的角度考虑。32位机器上有4个32位的通用数据寄存器:EAX,EBX,ECX,EDX。每个通用寄存器的低16位又可以单独使用,叫做AX,BX,CX,DX。最后,这四个16位寄存器又可以分成8个独立的8位寄存器:AH、AL等。因此,CPU取数据时或者是一个字节AH或者AL等,或者是两个字节AX,BX等,或者是4个字节EAX,EBX等,而没法一次取三个字节的数据。)如果该数据的偏移是0x00000002,那么CPU就可以先取一个short,然后再取一个short,两次取值完成一个int型数据的组合。但是如果偏移是0x00000004,正好是4字节对齐的,那么CPU就可以一次取出这个int类型的数据。所以,为了提高取值速度,一般编译器都会优化数据对齐方式。优化的标准是什么呢?大小不同的各种基本数据类型的数据该怎么对齐呢?下面的表格作出了总结:

基本数据类型的偏移
基本数据类型 占用内存大小(字节) 字节对齐方式(首地址偏移)
double / long long 8 8
int / long 4 4
float 4 4
short 2 2
char 1 1

其中,字节对齐方式(首地址偏移),表示的是该类型的数据的首地址,应该是该类型的字节数的倍数。当然,这是在默认的情况下,如果用#pragma pack(n) 重定义了字节对齐方式,那么情况就有点复杂了。一般来说,如果定义#pragma pack(n),而按照数据类型得到的对齐方式比n的倍数大,那就按照n的倍数指定的方式来对齐(这体现了开发者可以选择不使用推荐的对齐方式以获得内存较大的利用率);如果按照数据类型得到的对齐方式比n小,那就按照前者指定的方式来对齐(一般如果不指定对齐方式时,编译器设定的对齐方式会比基本类型的对齐方式大)。下面具体到不同类型的大小时,会举一些例子。现在,只要记住这两条规律就可以了。

上面只是基本数据类型,比较简单,一般复杂的组合数据类型,比如enum(枚举)、Union(联合)、struct(结构体)、class(类)。一个个来。

数组,数组是第一个元素对齐,以后的各个元素就对齐了。

enum,枚举类型,一般来说大小为4字节,因为4个字节能够枚举4294967296个变量,大小足够了。如果不够&

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值