C 语言之 struct 大小、首地址与内存对齐
被问到如下问题:
给定一个结构体中某个变量地址,可否得到结构体变量的地址?
答案是可以,但是对不同的场合有不同的结果;这与微处理器平台、编译器的处理不可分割。
首先,对于处理器,大尾端、小尾端的因素必须考虑;
其次:
一、 ANSI C 标准中并没有规定,相邻声明的变量在内存中一定要相邻。
为了程序的高效性, 内存对齐问题由编译器自行灵活处理, 这样导致相邻的变量之间可能会有一
些填充 字节。对于基本数据类型 (int char) ,他们占用的内存空间在一个确定硬件系统下有个确
定的值,所以,接下来我们只是考虑结构体成员内存分配情况。
1、Win32 平台下的微软 C 编译器 (cl.exe for 80 ×86) 的对齐策略:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
备注: 编译器在给结构体开辟空间时, 首先找到结构体中最宽的基本数据类型, 然后寻找内存地
址能被该基本数据类型所整除的位置, 作为结构体的首地址。 将这个最宽的基本数据类型的大小
作为上面介绍的对齐模数。
2) 结构体每个成员相对于结构体首地址的偏移量( offset )都是成员大小的整数倍, 如有需要编
译器会在成员之间加上填充字节( internal adding );
备注 :为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首
地址的偏移是否是本成员的整数倍,若是, 则存放本成员, 反之, 则在本成员和上一个成员之间
填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。