C语言-内存管理-结构体

首先,结构在C语言中也是一种数据类型,叫做聚组类型(还包括数组)。他和其他的数据类型是一样的,在定义一个结构体的时候,系统并不会为他真正的分配内存空间(定义的结构体变量要在编译的阶段才分配空间,而结构体指针要显示的使用malloca来分配空间),也就是说,在定义结构体这种数据类型的时候是不会分配内存空间的,只有在定义变量的时候,才会分配。

下面是摘自百度百科 对结构题存储的三点:

  1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除
  2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会 在成员之间加上填充字节
  3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节

结构体

1
2
3
4
5
struct s1{
  char a;
  int b;
  char c;
};

内存分配为:1+3+4+1+3=12
其中两个char后面的+3为填充字符

结构体

1
2
3
4
5
struct s1{
  int b;
  char a;
  char c;
};

内存分配为:4+1+1+2=8
其中两个char后面的+2为填充字符

相比之下,后面的顺序提高了存储空间的利用率

  • 编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能是该基本数据类型的整倍的位置,作为结构体的首地址。
  • 为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。
  • 结构体的总大小为结构体中最宽基本数据成员的整数倍。如有需要,编译器将会在结构体的添加填充字符。
  • 在组织数据结构的数据成员的时候,可以将相同类型的成员放在一起,这样就减少了编译器为了对齐而添加的填充字符。