C/C++ 中内存对齐--结构体

内存对齐指令

  1. 一般来说,内存对齐过程对 coding 者来说是透明的,是由编译器控制完成的

  2. 如对内存对齐有明确要求,可用 #pragma pack(n) 指定,以 n 和结构体中最长数据成员长度中较小者为有效值

  3. 如未明确指定时,以结构体中最长的数据成员长度作为内存对齐的有效值

以下如没有特殊说明,均视为情况 3 (未明确指定)计算

内存对齐的三条规则

另外需要注意的几点:

  1. 数组在内存中存储时是分开存储的,char 类型的数组每个元素是 1Byte,内存对齐时按照单个元素进行对齐;

  2. union(联合体)类型中的数据共用内存,联合的所有成员共用一段内存空间,存储地址的起始位置都相同,一般来说最大成员的内存宽度作为 union 的内存大小,主要的原因是为了节省内存空间,默认的访问权限是公有的,但是它同样要遵守内存对齐的原则,特别是第 3 条规则;

  3. C++ 中空结构体占用 1Byte;

  4. C++ 中空类同样是占用 1Byte的内存空间(剑指offer 2.2.1节中中提到,当声明该类型的实例的时候,必须在内存中占有一定的空间,否则无法使用这些实例,占用多少内存由编译器决定);

举例说明

例1

struct Test1 {
  int a;      // 4 -> 8
  double b;   // 8 -> 8
  char c;     // 1 -> 8
};

说明

例2

struct Test2 {
  int a;      // 4 -> 8
  double b;   // 8 -> 8
  char c[6];  // 6 -> 8
};

说明

例3

struct Test {
  int a;    // 4 -> 8
  double b; // 8 -> 8
  char c;   // 1 -> 8
};

struct Test3 {
  int a;    // 4 -> 8
  Test d;   // 24 -> 24
  double b; // 8 -> 8
  char c;   // 1 -> 8
};

说明

例4

struct Test {
  int a;    // 4 -> 8
  double b; // 8 -> 8
  char c;   // 1 -> 8
};

struct Test3 {
  int a;    // 4 -> 8
  Test d;   // 24 -> 24
  char c;   // 1 -> 8
};

说明

例5

union Test{
  char a[20]; // 1 -> 20
  int b;      // 4
  float c;    // 4
};

说明

例6

union Test{
  char a[20]; // 1 -> 20
  int b;      // 4
  float c;    // 4
  double d;   // 8
};

说明

字节对齐的原因:

Table of Contents