Skip to content

内存对齐 - 求结构体大小

Published: at 05:26 AM | 4 min read

内存对齐的原因

大部分的参考资料都是如是说的:

内存对齐规则

看下面几个例子就清楚了

假设在32位机器上,结构体中第一个成员: 起始位置 = 0,那么终止位置 = 起始位置 + 成员自身所占的字节数。 例子1:

typedef struct _AA
{
	char c; // 0 (第一个成员的起始位置为0)
	int n; // 4 - 7 (int占四个字节) 规则一
	short s; // 8 - 9 (short占两个字节,但不是最大成员的整数倍,所以需补齐) 10 - 11 规则三
}AA; // 最后,这个结构体所占字节数就是12

例子2:

typedef struct _CC
{
	char name[2]; // 0 - 1
	int id; // 4 - 7 规则一
	double score; // 8 - 15
	short grade; // 16 - 17
	AA aa; // 20 - 31 (本来起始位置是从18开始,但是18并不是最大成员int的整数倍,所以需从20开始) 规则二
}CC; // 最后,所占字节数为32

#pragma pack(n)

通过上面这条语句可以改变“对齐系数”,对以上对齐规则的影响是: 规则一中的“自身所占字节数”,规则二中的“这个子结构体中的最大成员所占字节数”,规则三中的“最大成员所占字节数”都要与 “对齐系数n”进行比较,取小者。 例子3:

// 不指定对齐系数,即采用默认对齐系数
typedef struct _DD
{
	char c; // 0
	double d; // 8 - 15
	short s; // 16 - 17 18 - 23
}DD; // 大小是24

例子4:

// 指定对齐系数为4
#pragma pack(4)
typedef struct _DD
{
	char c; // 0
	double d; // 4 - 11 (double自身字节数是8个字节,与4进行比较,取4的倍数)
	short s; // 12 - 13 14 - 15 (最大成员字节数8也与4进行比较,补齐时取4的倍数)
}DD; // 大小是16

以上就简单的介绍了一下结构体大小的计算方法,如有不正确的地方欢迎指正。

2011-07-09