分析结构体所占存储空间

代码示例展示了在不同系统和位数环境下,结构体占用内存的不同。文章解释了CPU为提高效率采用的字节对齐策略,以及如何考虑最大类型对齐规则。在分析结构体内存占用时,必须考虑字节对齐导致的空间浪费。练习题要求分析特定结构体的存储空间大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面有这样一段代码,请试着分析结果:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//struct aaa{
//	int num;
//	char name[20];
//	double age;
//	char sex;
//};
//int main(){
//	struct aaa x;
//	printf("%d",sizeof(x));
//}

struct animals
{
char dog;				//1
unsigned long cat;		//4(在Ubuntu环境下为8)
unsigned short pig;		//2
char fox;				//1
};
int main(){
	struct animals x;
	printf("%d",sizeof(x));
}

我们将上面的这段代码运行在32位和64位环境中会出现不同的结果,放在win和Ubuntu下也会出现不一样的结果,这是为什么呢?
首先我们要知道两个知识点:
1、32位系统同时处理的最大字节数为4字节,而64位系统能同时处理最大字节数为8字节;
2、win64中long类型的变量大小为4byte,Ubuntu下以64位编译,long类型的大小为8byte;
补充:32位系统下指针变量大小为4byte,64位系统下指针变量的大小为8byte;
内存分配分析

cpu会采取字节对齐以及用空间换效率的方式存储数据

如上图所示:cpu为了提高运行效率,会用空间换时间,在放入一个char之后,只剩下3个字节的空间,不能够完整的放入一个int类型,那怎么办呢,现在有两种方案:

  • 一种是先放入一部分的int,剩下的一个放在另外开辟的一块内存中,这样做空间利用率会得到提高,但cpu需要更多的步骤读取内存中的数据(假如cpu一次能读取4字节,第一次读到的是int的前三个字节,需要再读取一次才能将这个int全部读取完)。
  • 另外一种是直接将完整的int类型放入新的内存,这样确实会浪费掉一部分空间,但却大大减少了cpu读取内存的步骤,有效的提升了数据操作的效率。

而我们的cup就是使用第二种方案,所以在分析内存的时候,不能简单的将所有变量类型与数量相乘再相加,还应当考虑到提高cup运算效率所采取的存放方式。

例如图中的xxxx结构体:

short a //2 char b //1 int c //4 char d //1 char e //1 double f //8 short g //2

若按照简单相加,那么只会占用19字节,这坑定是不对滴!

同时前面提到了32位系统与64位系统处理能力的不同,所以在不同的系统中,占用也不同,应当分开讨论:

32位:一次能处理4字节,所以我们将图中最大宽度设置为4方便分析。首先放入short,占2字节,剩2字节,能放入char,剩1字节,下一个变量为int,放不下,所以只能新开内存,将第二层放int,第三层放char,还剩3字节,再放一个char,剩下2字节,不够double的8字节,于是将第四层,第五层都放double,第六次放short。所以一共是4*6=24字节。但是第6层还剩下2字节,为啥不是占用22字节呢?

这是因为在xxxx这个结构体中,最大的类型为double,占用8字节,我们的内存应当与最大字节对齐,所以剩下的也算作被xxxx结构体占用了。对此我们可以对比yyy结构体,他占用的是6字节而不是8字节,就是由于yyy结构体的最大类型为short,占2字节,而无论是32,还是64都会剩下2字节,这个不会被占用。

还有一个细节,那就是为什么yyy中的short不能紧贴char放置呢?原因还是同上—应当与最大类型对齐!

练习题:

1、分析以下结构所占的存储空间大小:

 struct animals
 {
     char dog;
     unsigned long cat;
     unsigned short pig;
     char fox;
 };

2、假设有以下说明和定义: 则语句 printf(“%d”, sizeof(struct creature)+sizeof(berry));的执行结果是?

typedef union
{
   long i;
   int k[5];
   char c;
} fruit;
struct creature
{
   short cat;
   fruit apple;
   double dog;
};
fruit berry;

答:T1:
不同颜色代表的不用的数据类型
t1-1
t1-2
t1-3
T2:
t2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值