http://www.titilima.cn/readblog.php?id=48
应3月下旬时候wencui大姐之邀,在此将字节对齐的问题小小总结一下。我并不打算把这个总结写成学究派那种苛求“回”字四样写法的样子,因此这里只是简要总结是什么、为什么的问题。我在其中给了几个最简单的小例子来说明这一问题,顺便说一句,我贼反感某些考试中在字节对齐上大做文章的手法——一个sizeof就能搞定的问题,装TMD什么孙子。
1、什么是字节对齐以及为什么要字节对齐。所谓字节对齐就是C/C++编译器为了加速CPU寻址速度而采用的一种策略,通常的表现是将结构中某些不足CPU字长的成员填入若干字节的垃圾值使整个结构的大小成为CPU字长的整数倍。(所谓CPU的字长,可以简单地理解为一个sizeof(int)的大小。)
2、字节对齐的例子。在此列出一段代码,附有相关注释,不多解释。
struct A // size: sizeof( int ) * 2
{
char c;
int n;
};
struct B // size: sizeof( int ) * 3
{
char c1;
int n;
char c2;
};
struct C // size: sizeof( double ) * 2
{
int n;
double lf;
};
3、可以说字节对齐是一种以空间换时间的做法。但如果某种情况下,程序员需要将struct A的10000个成员写入文件,那么在32位系统中,这个文件就会浪费30000个字节的空间,浪费率达到了37.5%。这时候的解决方式是改变默认的字节对齐方式,具体实现是利用了#pragma链接器指令。下面的例子使用了1字节的对齐,也就是不对齐。
#pragma pack( push, 1 )
struct D // size: 1 + sizeof( int )
{
char c;
int n;
};
#pragma pack( pop )
该指令的使用方法不止此一种,更多信息请参考MSDN。
4、1字节的对齐还有其它一些魔术般的作用,譬如可将指令的机器码写入某种结构,然后使之执行。ATL的CWndProcThunk就采用了这种手段,参见atlwin.h。