0
点赞
收藏
分享

微信扫一扫

结构体如何计算内存大小+联合体+位段

扬帆远航_df7c 2022-03-30 阅读 106
c语言c++

目录

前言

1.结构体内存对齐

1.1规则

1.2举列

1.3 结构体嵌套求大小

1.4为什么存在内存对齐

 1.5 修改默认对齐数

1.6 结构体传参

2.位端

 3.联合(共用体)


前言

结构体存在内存对齐,所以对于不了对齐的是很难计算结构体的大小

1.结构体内存对齐

1.1规则

1.2举列

#include<stdio.h>

struct S1
{
	char a;
	int i;
	char b;
};

struct S2
{
	char a;
	char b;
	int i;
};

int main()
{
	struct S1 s1;
	struct S2 s2;
	printf("%d\n", sizeof(s1));
	printf("%d\n", sizeof(s2));
	return 0;
}

在VS编译器下,明明变量内容是一样的,为什么算出的结果不相同

这是因为结构体的对齐

在VS编译器下,默认对齐数是8

 假设从s1在内存中是从我画的地方开始的,对于根据规则,从我画的地址开始,所以a在

最初的位置,也就 我画的0处,然后是int i,因为int 字节是4,在VS环境下与8比较4比较小所以对齐数是4,放的位置就应该在4的倍数处,所以放在橙色处,占是四个字节, 然后是char b ,占一个字节与8比比较所以他的对齐数位1,接着放,然后根据,结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍 , 找到结构体中最大的是4,所以结果是4 的倍数,但是根据画图有9个byte,所以就是12byte。

 同理对于s2,

 因为,要从0偏移量开始,所以a在,红色区域,然后算b,8小于b的字节数(1),所以对齐数是1,就从这里开始,b在黄色区域,然后int, 4 < 8,所以对齐数是4,i的位置应该是4偏移量的倍数,也就是从4 开始,在s2中,最大对齐数是4,所以结果应该是4,的倍数,刚好就是8

1.3 结构体嵌套求大小

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

 根据规则可以知道,最大对齐是俩个中最大对齐数也就是8,(上面写在结构体旁边的就是 该的字节大小),刚好我们算出来的结果就是32,是8 的倍数,所以成立

1.4为什么存在内存对齐

用法总结 如果我们既要满足对齐,又要节省空间

 1.5 修改默认对齐数

#pragma pack(1)//设置默认对齐数为1
struct S2
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

int main()
{
	//输出的结果是什么?
	printf("%d\n", sizeof(struct S2));
	return 0;
}

在这里我设置为了1,就是所说相当于没有对齐数,直接开始,这个我就不画图了,自己画,在这里结果就是6(在这里最大对齐数是1,看不太懂请看最前面规则)

1.6 结构体传参

结论:

结构体传参的时候,要传结构体的地址。

2.位端

位段的声明和结构是类似的,有两个不同:

 内存分配

 位段的跨平台问题

 3.联合(共用体)

联合类型的定义

//联合类型的声明
union Un
{
	char c;
	int i;
};

int main()
{
	//联合变量的定义
	union Un un;
	//计算连个变量的大小
	printf("%d\n", sizeof(un));
}

 

 

修改i ,就等于修改了,c, 公用的是从起始位开始的。

特点

联合体计算

 

在这里算大小也是需要对齐的 ,

 Un2同理就不讲解了

注意

修改联合体的公共部分是一同修改的

举报

相关推荐

0 条评论