在之前的文章中,笔者就结构体的简单定义,初始化,等内容,进行了简单描述!!但是,对于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.性能原因
数据结构(尤其是栈)应该尽可能地在自然边界上对齐,原因在于:为了访问未对其的内存,处理器需要做两次内存访问,而对齐的内存访问,仅需要访问一次!
总的来说:
结构体的内存对齐是拿空间换取时间的做法!
那么设计结构体的时候,我们既要满足对齐,又要节省空间,就要做到:
让占用空间小的成员尽量集中在一起!!