的地址分配方法
点击:
结构体中的变量 item 在结构体中相对于首地址的偏移量应该是
X 的倍数,X 由
如下式子确定:X=min(n,sizeof(item))
,举个例子 (设 n 为 8):
struct Test { char c1; char c2; int i}; 如果定义了变量 Test t ,那么在存储
t 的 i 时 X
就应该是 min(8,sizeof(int))即为 4 的倍数,即 i 相对于结构体首地址的偏移量
必须是 4 的倍数,所以 t
的大小就应 该为 8 字节(在 c1 和 c2 后填充了两个字节以
满足前述条件)。对于 struct { char c1; char c2}不会出现填充的的情况,每个成员
相对首地址的偏移量也满足是 X 的倍数(此时 X 为 1),其大小为 2 字节。
验证程序:
#include <stdio.h>
main()
{
struct Test
{char c1;
char c2;
int i;
};
struct Test t;
t.c1=1;
t.c2=2;
t.i=3;
printf("%d %d %d %d\n",sizeof(t.c1),sizeof(t.c2),sizeof(t.i),sizeof t);
}
输出:1148
而对于结构 struct {char c1; double d;},默认情况下这种结构体变量占用 16 字节
(在 c1 后填充了 7
个字节以满足字节对齐)。 如果强制编译器以 4 字节对齐,即
在声明这种结构的变量前面有#pragma pack (4),此时 X 为 4,则此种类型结构体变
量占用的内存为 12
字节。
再看
struct {char c1; double d; char c2;}; 在默认字节对齐的方式下,输出其大小为
24
,呵 呵,这是因为编译器还有一条规定:结构体变量的大小必须要为 X(同上
定义)的倍数,如果不满足,就会在最后一个成员后填充最少字节数以满足此条件。
如果 定义此结构体前有#pragma pack(4),则输出大小为 16
。
还有一种特殊情况,就是空结构体。在 Visual C++
下其 大小为 1,即 struct{}类型
的变量在 VC 下输出其大小是 1,解释就是 VC 为每个结构体变量分配一个字节的
内存,以使该变量有个地址;而在 gcc
下输 出其大小为 0,我的理解是既然此结构
体一个成员都没有,程序中就不会访问它,因此也不必分配内存,如果编译器碰到
有访问此结构体成员的情况就会报错。
最后一种情况,结构体成员中有结构体成员的情况,
如 struct test1 { char c1; int i ; char c2 ;};
struct test2 { int i; struct test1 t1; char c2; };此时考虑在确定上述的 X
时会把 t1 拆
散成基本数据类型来处理,而考虑 test2 结构大小时又会把 t1 作为一个整体来对待,