我们写结构体的时候常常会发现,编译器为了按成一些文件操作,常常会在给成员开辟内存的时候,出现一些“缝隙”,我经过自己做实验发现了这些问题:
我们来看内存对齐的定义:编译器为了优化代码,往往会根据变量的大小,将其指定到合适的位置,即称为内存对齐。
然后我们来看下面一个现象:
如果源代码如下:
通过编译器的跟踪功能,我们可以看到:
&m 0x0012ff70
&m.usA 0x0012ff70
&m.ulB 0x0012ff74
&m.usC 0x0012ff78
&m.usD 0x0012ff7a
&m.ulE 0x0012ff7c
这样的话,也就是说明,出现了所谓“内存对齐”的现象,,由于32位的CPU是按4字节对齐的,usA的长度是2字节,ulB的长度是4字节,这意味着这两个变量的地址将不是连续的,它们之间将会有2字节的空隙。这个就会为fread, fwrite等函数的操作造成困难,导致数据的读写错误,因为我们需要的数据很可能被填充到那个没有使用的空隙里面了。所以我们需要指示编译器,让它不要按4字节对齐:
其中第一个#pragma pack(2)预处理指令指示编译器,下面的代码所涉及到的变量分别使用2字节对齐,第二个#pragma pack()预处理指令用以恢复编译器的默认对齐宽度。这样便不会出现我们所不希望看到的那些空隙。
我们看到内存的分配:
&m 0x0012ff70
&m.usA 0x0012ff70
&m.ulB 0x0012ff72
&m.usC 0x0012ff76
&m.usD 0x0012ff78
&m.ulE 0x0012ff7a
这样,内存的分配就正常了。