如何计算结构体的大小
-
结构体变量的首地址,必须是结构体变量中"最大基本数据类型所占字节"的整数倍
-
结构体变量中的每个成员相对于结构体首地址的偏移量都是该成员基本数据类型所占字节的整数倍
-
结构体变量的总大小,为结构体变量中"最大基本类型数据成员所占字节数"的整数倍
对齐原因
-
平台原因(移植原因) 不是所有的硬件平台都能访问任意地址的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据的,否则抛出硬件异常。
-
性能原因 数据结构(尤其是栈),应该尽可能在自然边界上对齐,因为在访问未对齐的内存时,处理器需要访问两次,而对齐的内存处理器只需要访问一次。
如何在设计结构体的时候,既要满足对齐,又要节省空间
按数据类型占用的字节数在结构体中按从小 到大改变或从大到小改变其成员位置
设计一个简单的结构体
struct s {
char s1;
int s3;
char s2;
}s;
结构体大小为12
将结构体中的数据元素按从小到大排列
struct s {
char s1;
char s2;
int s3;
}s;
结构体大小为8
将结构体中的数据元素按从大到小排列
struct s {
int s3;
char s1;
char s2;
}s;
结构体大小为8
不定义结构体变量,如何计算结构体成员的相对偏移量
定义一个宏
#define OFFSET(type,filed) (int)(&((type*)0)->filed)
type 对应结构体类型
filed 对应结构体成员
柔性数组
结构体中最后一个元素允许是未知大小的数组 ,这个数组就是柔性数组。 但结构中的柔性数组前面必须至少一个其他成员 ,柔性数组成员允许结构中包含一个大小可变的数组,sizeof()返回的这种结构大小不包括柔性数组的内存。
柔性数组的作用
1.减少内存的碎片化
提高访问速度 使用柔性数组的结构体一次malloc 结构体内的元素空间连续 也减少了内存碎片化
2.方便管理内存缓冲区
若不使用柔性数组 使用指针的话 会浪费一个指针的空间 而且需要先申请整个结构体的空间 然后再申请指针的空间 需要进行两次malloc free也需要先释放结构体内的空间再free结构体的