如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)

举报
念君思宁 发表于 2023/02/13 13:16:10 2023/02/13
【摘要】 如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)

在之前的文章中,笔者就结构体的简单定义,初始化,等内容,进行了简单描述!!但是,对于int  ,double ,float ,char 等类型都有自己的大小,但是,对于一个结构体,它的大小该如何计算呢???确实是一个疑问??这个也是不少老铁,在刚学结构体时候的最大煎熬!下面,笔者来带领大家熟悉一下,结构体大小的计算!!

在讲解之前,需要大家知道一下几点:

1.结构体的第一个成员,直接对齐到相对于结构体变量起始位置为0的偏移处!!

2.从第二个成员开始,要对齐到某个对齐数整数倍的偏移处!

对齐数:结构体成员自身大小和默认对齐数的较小值!

在VS中,默认的对齐数为:8

Linus环境不设默认对齐数(对齐数是结构体成员的自身的大小)

3.结构体的总大小,必须是最大对齐数的倍数!!每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数!!

4.如果嵌套结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小:就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

下面笔者用代码加解析的方法来演示一下:

#include <stdio.h>
 
struct s1
{
	char c1;
	int i;
	char c2;
};
 
int main()
{
	printf("%d\n", sizeof(struct s1));
	return 0;
}

上面定义了一个结构体,里面存放有:char c1;    int i;   char c2; (我们先注意一下,结构体里面的先后顺序) char 占一个字节,Int 占4个字节!但是对于运行结果:12个字节????什么鬼这是??

 不相信的各位老铁,可以在VS的x86环境下进行实现!读者可以自己进行验证!!

 对于结构体的仔细划分为:

 经过上面的笔者必须知道的部分:1,2,3,三点,我们可以有:

但是,笔者将上面的结构体的顺序,稍微改写一下:

struct s2
{
	char c1;
	char c2;
	int i;
};

请注意一下,先后顺序!!

对于这个代码,该结构体的大小,又是多少呢???想必,到此为止,各位老铁,不再是:1+1+4=6个字节了吧!!

请看这代码的运行结果:

 但是,这个结果是8,这个又是为什么呢??各位老铁,可以根据,前面的那个案列来分析一下:

 对于上面两个案列的简单讲解,想必大家也能理解了:如何来求结构体大小的方法!!

下面,笔者来带领大家,求一下:结构体成员,相对于起始位置的偏移量!!

offset是一个宏!!是用来计算:结构体成员相对于起始位置的偏移量的一个宏!

使用语法为:

offsetof(type ,member);

type 是指:哪个结构体类型! ,member 是指:成员名!!

下面笔者用代码加解析的方式来带领大家了解一下:

 
#include <stdio.h>
#include <stddef.h>
 
struct s1
{
	char c1;
	int i;
	char c2;
};
 
int main()
{
	printf("%d\n", offsetof(struct  s1 , c1));   //0
	printf("%d\n", offsetof(struct  s1, i));     //4
	printf("%d\n", offsetof(struct  s1, c2));    //8
 
	return 0;
}

上面代码的运行结果为:

 这个在,笔者的讲解过程:

 因此,结构体的总大小,必须是:最大对齐数的倍数

同理可得,我们也可以对

struct s2
{
	char c1;
	char c2;
	int i;
};

来进行同样的道理分析:

 
#include <stdio.h>
#include <stddef.h>
 
struct s2
{
	char c1;
	char c2;
	int i;
};
 
int main()
{
	printf("%d\n", offsetof(struct  s2, c1));   //0
	printf("%d\n", offsetof(struct  s2, c2));     //1
	printf("%d\n", offsetof(struct  s2, i));    //4
 
	return 0;
}

 想必现在,大家对于该结构体的大小,目前没有什么问题了吧!!

对于嵌套部分的结构体,我们一样可以用这样的方法来进行求解!!相信大家都是可以求出来的!!

经过上面的结构体对齐的方法讲解:想必大家也有着:为什么存在内存对齐??有着疑惑!!下面笔者来进行简单讲解一下:

1.平台原因

不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处,取某些特定类型的数据,否则,抛出硬件正常!

2.性能原因

数据结构(尤其是栈)应该尽可能地在自然边界上对齐,原因在于:为了访问未对其的内存,处理器需要做两次内存访问,而对齐的内存访问,仅需要访问一次!

总的来说:

结构体的内存对齐是拿空间换取时间的做法!

那么设计结构体的时候,我们既要满足对齐,又要节省空间,就要做到:

  让占用空间小的成员尽量集中在一起!!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。