第三章 预处理
因为这一节的读书笔记是关于:内存对齐的,我觉着《C语言深度解剖》这本书关于这个主题讲得不太清楚,所以自己再看了一些资料,读到了一篇关于内存对齐研究的好文章(链接):内存对齐的规则以及作用 verygood!的一篇文章! 在读完此篇文章的基础上写下,下面的读书笔记。
我们可以利用#pragma pack()来改变编译器的默认对齐方式:
#pragma pack(n) //编译器将按照n字节对齐
......
......
#pragma pack() //编译器将取消自定义字节对齐方式
在#pragma pack(n) 和 #pragma pack() 之间的代码按n字节对齐。
虽然说指定了按n字节对齐,但并不是所有的成员都是以n字节对齐。其对齐的规则:每个成员按其类型的大小和指定对齐n的大小中比较小的那个,(即:min(n,sizeof(item))),并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补齐字节。
看下面例子:
#pragma pack(8)
struct TestStruck4
{
char a;
long b;
}
struct TestStruck4
{
char c;
TestStruck4 d;
long long e;
};
#pragma pack();
问题:
1) sizeof(TestStruck4) = ?
2) sizeof (TestStruck5) =?
[附加:C语言的C99标准扩展了新的整数类型long long ,long 是32位宽,占4个字节;long long 通常被定义为64位宽,占8字节]
解析:TestStruck4 中,成员a是1字节,默认按1字节对齐,指定对齐参数为8,这两个值中取1(即:min(8,1)),a按1字节对齐;成员b是4字节,(min(8,4)),b按4字节对齐,所以sizeof(TestStruck4) =8
TestStruck4 的内存布局 1xxx,1111
TestStruck5 中,c 按1个字节对齐;d是个结构,默认对齐方式是:所有成员中最大数据的成员的对齐长度,即成员d按4字节对齐;而e是8字节,所以按8字节对齐(以8的倍数为起始地址对齐);
c d.a d.b e
TestStruck5 的内存布局 1xxx,1111,1111,xxxx,1111,1111
所以sizeof(TestStruck5) =24