关于sizeof函数计算结构体类型空间大小时遇到的难题

电脑杂谈  发布时间:2019-10-08 23:04:49  来源:网络整理

子宫体大小正常范围_怎么计算鸡鸡大小公式_计算结构体大小

更多帖子

yufei_qf

Bbs1

本版专家分:0

结帖率 100%

说到结构体类型空间大小的问题,就到说一下内存对齐的疑问,我查了一些资料《C语言深度剖析》,书上面说的是,如果没有自定义字节对齐数,变量会根据它本来对齐,这个也可以理解,但是我今天有这么一个问题,我写了这么一个结构体:

typedefstruct_teststu

{

uint8A;

uint16B;

uint32C;

uint32D;

}TestStu;

这个之后A是1字节对齐,B是2字节对齐,A和B中间有1个字节的空,C和D都是4字节对齐,这个结构体sizeof的结果是占12个字节没问题。

那我把结构体改成这种:

typedefstruct_teststu

{

uint16B;

uint32C;

uint8A;

uint32D;

}TestStu;

此时B占2个字节,C占4个字节,B和C中间有2个字节的空,接下来A占1个字节,D占4个字节,A和D中间有3个字节的空,这个结构体sizeof的结果是占16个字节,也没有问题。

当我把结构体改成那样时:

那我把结构体改成这种:

typedefstruct_teststu

{

uint16B;

uint32C;

uint32D;

uint8A;

}TestStu;

此时B占2个字节,C占4个字节,B和C中间有2个字节的空,接下来D占4个字节计算结构体大小,A占1个字节,D和A中间没有空,那这时sizeof的结果会是多少呢?我的理解这个之后sizeof的结果应当是13,但是我实测结果,是16。

于是我就不理解了,这是为什么呢,我又找了资料,无果,没有找到讲到这方面的书。所以只能在这里向大佬们求助,,,

问题点数:分

计算结构体大小_子宫体大小正常范围_怎么计算鸡鸡大小公式

-->

更多帖子

636f6c696e

Bbs6

本版专家分:6973

Blank

GitHub绑定GitHub第三方账户获取

Blank

红花2019年7月 C/C++大版内专家分月排行榜第一

Blank

黄花2019年9月 C/C++大版内专家分月排行榜第二

2019年6月 C/C++大版内专家分月排行榜第二

2019年4月 C/C++大版内专家分月排行榜第二

2019年3月 C/C++大版内专家分月排行榜第二

2019年2月 C/C++大版内专家分月排行榜第二

结构体的最后大小应该是其最大成员大小的整数倍,所以A的前面就会预留3个字节。

更多帖子

yufei_qf

Bbs1

本版专家分:0

引用1楼636f6c696e的回复:结构体的最后大小应该是其最大成员大小的整数倍,所以A的前面就会预留3个字节。

这是在哪本书里讲的,求教大佬

更多帖子

tongshou

Bbs2

本版专家分:384

结构体的对齐问题,不仅仅要考量单个结构体,还需要考虑结构体构成函数(array)时、相应的成员应当位对齐。显然里面说的13字节进行array时能够位对齐,如果补3个字节空位到16字节,再进行array时,可以实现位对齐。

位对齐要求,与平台存储分页操作方便有关。

”如果没有自定义字节对齐数,变量会根据它本来对齐“,这句话好像不对,应该与编译器设置有关(缺省位对齐)。

计算结构体大小_子宫体大小正常范围_怎么计算鸡鸡大小公式

更多帖子

tongshou

Bbs2

本版专家分:384

引用1楼636f6c696e的回复:结构体的最后大小应该是其最大成员大小的整数倍,所以A的前面就会预留3个字节。

这个就是最简单的计算标准。

更多帖子

自信男孩

Bbs8

本版专家分:48265

Blank

黄花2018年10月 C/C++大版内专家分月排行榜第二

2018年6月 C/C++大版内专家分月排行榜第二

2018年1月 C/C++大版内专家分月排行榜第二

2017年12月 C/C++大版内专家分月排行榜第二

2017年8月 C/C++大版内专家分月排行榜第二

Blank

蓝花2018年5月 C/C++大版内专家分月排行榜第三

2018年4月 C/C++大版内专家分月排行榜第三

2018年3月 C/C++大版内专家分月排行榜第三

2018年2月 C/C++大版内专家分月排行榜第三

2017年11月 C/C++大版内专家分月排行榜第三

2017年10月 C/C++大版内专家分月排行榜第三

2017年9月 C/C++大版内专家分月排行榜第三

2017年6月 C/C++大版内专家分月排行榜第三

2017年5月 C/C++大版内专家分月排行榜第三

2017年4月 C/C++大版内专家分月排行榜第三

2017年3月 C/C++大版内专家分月排行榜第三

B后面补2个字节,A后面补3个字节,所以是16.另外,结构体对齐得到值是4个倍数,而不是一个13

怎么计算鸡鸡大小公式_计算结构体大小_子宫体大小正常范围

更多帖子

guocherish

Bbs1

本版专家分:0

结构体的最后大小应该是其最大成员大小的整数倍,这个结构体是4个字节,所以A的后边就会预留3个字节,一共16

LuLu-jianfeng

Bbs1

本版专家分:0

说实话,基本用不到这些,一般直接sizeof,然后再用到其它方面就好了

更多帖子

拥抱Linux

Bbs4

本版专家分:1365

Blank

蓝花2019年5月 C/C++大版内专家分月排行榜第三

对于结构体类型,成员的存储对齐,除了有结构体外部的对齐,还有整个结构体本身在存储中的对齐。

看过的一个参考资料,还是非常具体、形象的,截图如下:

(1)

(2)

另外,结构体本身在存储中的对齐基数可以用宏alignof来受到,看资料是C11之后支持的,相关头文件为<stdalign.h>。

例如:


#include <stdalign.h>
// 获取结构体变量TestStu本身的内存对齐基数,数值的单位是字节
printf("Alignment of int is %zu\n", alignof(TestStu)); 

输出结果是:

Alignment of structure TestStu is 4

意思是,结构体变量TestStu在存储中占用的空间,要以4个字节为基数来对齐。

从后面的图片也可以看出,结构体成员没有占据的部分,就以空字节来占位(padding)。

另外,成员之间也不必定是密切挨在一起的,各个类型都有相应的「地址的数值」的限制。

简单地说,占单个字节的类别没有限制,其它的占偶数个字节的类别都有限制,比如int型在32位、64位x86机器上占4个字节,它的地址的数值应该是4的整数倍,也就是0x7fff....00这么的地址。所以即使一个char和一个int顺序定义的话,在内存里,它们俩也不会紧挨在一起,而是两者之间有空的占位字节(padding)。

总结一下:

你看的书里提到的「如果没有自定义字节对齐数,变量会根据它本来对齐」这句话是对的,但是准确到你的事例,不能只考量结构体成员而忽略了结构体变量本来——结构体变量只是变量啊!

还有一点就是,在必须对齐的状况下,变量对地址的数值只是有要求的,不是见到一个地址就放进去的。

希望能帮到你。:)

子宫体大小正常范围_怎么计算鸡鸡大小公式_计算结构体大小

PS.

在gcc的文档里也说过,数据在内存里也可以不对齐,直接一个紧靠近下一个也行,只是这种的读取效率就低多了。对齐是以空间换时间。

更多帖子

拥抱Linux

Bbs4

本版专家分:1365

Blank

蓝花2019年5月 C/C++大版内专家分月排行榜第三

勘误一下:

上面写的「比如int型在32位、64位x86机器上占4个字节,它的地址的数值应该是4的整数倍,也就是0x7fff....00这么的地址。」把地址的值写错了,十六进制下4的倍数不是这样的,应该是二进制下的.....00这么的地址。一直习惯看见十六进制的地址,一下子没改回来。不好意思啊!其它内容必须没有笔误。

Bbs2

本版专家分:216

这个是不必定的计算结构体大小,因系统而已。有些系统需要把每位成员都放到偶数地址上,或4的倍数的地址上,会存在为使用的缝隙。––CPrimerPlus

更多帖子

Mr_sandman1994

Bbs1

本版专家分:65

两条原则:

1.把数据的地址除数据的大小,如果相除结果为0(整除),那么数据就是对齐的。

2.结构最后大小是所对齐数据中最大数据的整数倍,如果不够需要进行填充。

根据这两条,那个数据结构是16,没有问题

更多帖子

Travor_LZH

Bbs1

本版专家分:0

把结构体的末尾改成:

}__attribute__(packed);

就可以避免对齐,从而超过需求。这在操作系统开发中比较有用


本文来自电脑杂谈,转载请注明本文网址:
http://xinshanjie.com/a/jisuanjixue/article-125631-1.html

    相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...