结构体内存计算

2021/10/3 7:11:55

本文主要是介绍结构体内存计算,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.结构体的内存规则

        1. 第一个成员在与结构体变量偏移量为0的地址处。

        2. 其他成员变量要对齐到对齐数的整数倍的地址处。

        对齐数 =  min(编译器默认的对齐数 , 该成员大小 )

        3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

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

2.简单理解一下

        第1.2点,其实简单理解就是从第一种类型成员变量开始放,一旦有成员变量与上一种变量不同就需要对齐到要放的变量大小的整数倍。就如下左图,先放一个char型成员,再放置一个int型的。int型大小是4个字节,不能从第二个位置开始放,要跳过之前的四个位置,从第五个字节开始放。

        第3点就是一个最后对齐的过程,如下左图中,放到现在是有八个格子,我们最大的成员变量是4个字节,对齐到4的整数倍就是8,后面不需要再补了。所以一个char加上一个int总大小就是8个字节。但是如果是先放的int再放char,那么就会像下右图。好像第五个位置就放完了,但是由于中间有个int是4个字节,于是要往后对齐加上3个,总共8个就是整个的内存大小。

        第4点就是在说如果你要计算的结构体中,成员包含了结构体成员,那么你就在结构体成员算出它的最大对齐数来当作这个结构体成员的对齐数。

3.计算一个例子

struct S3 
{ 
	double d; 
	char c; 
	int i; 
};
struct S4 
{ 
	char c1; 
	struct S3 s3; 
	double d; 
}; 
int main()
{
	printf("%d\n", sizeof(S4));
	return 0;
}

         这里我们在vs编译器下运行结果应该是32。具体我们可以这样计算验证一下。

        要算结构体s4的大小,因为它包含了s3,我们先算一下s3的大小。s3中double占8个字节,下一个成员是char类型,大小为1,任何整数都是1的整数倍,所以紧接着存上。在下一个就是int,大小是4,存储char后整个大小为9,不是4的整数倍,需要往下对齐到12,再开始存int类型成员。到int也存好了总共是16。我们看一下是否还需最后对齐,最大对齐数是double的8,16是8的整数倍,不需要对齐,于是s3的大小就是8。而且s3在s4中作为成员,他的对齐数是他本身的最大对齐数8。

        接下来我们再从s4第一个成员开始计算,第一个char放在第一个位置。第二个是s3,对齐数8,跳过7个字节,从整体的第9个字节开始存储,本身内容为16个字节。到此使用了8+16,24个字节,刚好是下一个double的整数倍,于是下一个成员字节连续存储。那么现在总共就是32个字节。最后观察一下是否还需要往后对齐。s4的三个成员,对齐数分别是4,8,8,最大对齐数很容易知道就是8。32是8的整数倍,不需要再往后对齐了。于是,到此我们成功计算得出s4的大小是32。

 总结

        结构体的存储,其实就是一种计算机以空间换时间的做法。将各个成员变量在内存中以整数倍对齐后,能方便一次访存,提高时间效率。



这篇关于结构体内存计算的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程