为结构体分配内存时,分配的内存大小至少是各个字段的长度和。不过,实际长度通常会大于这个和,因为结构体的各字段之间可能会有填充。某些数据类型需要对齐到特定边界就会产生填充。比如说,短整数通常对齐到能被2整除的地址上,而整数对齐到能被4整除的地址上。
这些额外内存的分配意味着几个问题:
- 要谨慎使用指针算术运算;
- 结构体数组的元素之间可能存在额外的内存。
比如说,如果为上一节中出现的Person
结构体的实例分配内存,会分配16字节——每个元素4字节。下面这个版本的Person
用短整数来代替无符号整数作为age
的类型。这样分配的内存大小还是一样,因为结构体末尾填充了2字节:
typedef struct _alternatePerson {
char* firstName;
char* lastName;
char* title;
short age;
} AlternatePerson;
在下面的代码片段中,我们声明了Person
和AlternatePerson
结构体的实例,然后打印结构体的长度。它们的长度相同,都是16字节:
Person person;
AlternatePerson otherPerson;
printf("%d\n",sizeof(Person)); // 打印16
printf("%d\n",sizeof(AlternatePerson)); // 打印16
如果我们创建一个AlternatePerson
的数组(如下所示),那么每个数组元素之间会有填充,如下图所示。阴影区域表示数组元素之间的空隙。
AlternatePerson people[30];
如果我们把age
字段移到结构体的两个字段中间,那么空隙就处于结构体内部。根据访问结构体的方式,这可能会很重要。