数据对齐:是指数据所在的内存地址必须是该数据长度的整数倍。DWORD数据的内存起始地址能被4除尽,WORD数据的内存起始地址能被2除尽。X86 CPU 能直接访问对齐数据,当它试图访问一个未对齐的数据时,会在内部进行一系列的调整。这些调整对于程序来说是透明的,但是会降低运行速度,所以编译器在编译程序时会尽量保证数据对齐。
CPU访问内存的时候,如果数据是对齐的,则访问效率会提高很多。一般情况下,地址总线总是按照对齐后的地址来访问的。比如想得到0x00000001开始的4字节内容,系统首先需要以0x0000000读4字节,从中取得3个字节,然后再用0x00000004作为开始地址,获得下一个4字节,再从中获得第一个字节,通过两次组合得到你想要的数据。但是如果地址一开始就是对齐到0x00000000,那么系统只要一次读写就好了。
为了性能方面的考虑,编译器会对结构进行对齐处理。
同样一段代码,来看一下VC, Dev C++和LCC着3个不同的编译器编译出来的程序的执行结果:
#include<stdio.h>
int main()
{
int a;
char b;
int c;
printf("0x%08x ",&a);
printf("0x%08x ",&b);
printf("0x%08x ",&c);
return 0;
}
用VC编译后的执行结果:
0x0012ff7c
0x0012ff7b
0x0012ff80
变量在内存中的存储顺序为:b(1字节)--a(4字节)--c(4字节)
用Dev C++编译后的执行结果:
0x0012ff7c
0x0012ff7b
0x0012ff74
变量在内存中的存储顺序为:c(4字节)--中间隔3个字节--b(1字节)--a(4字节)
用LCC编译后的执行结果:
0x0012ff6c
0x0012ff6b
0x0012ff64
变量在内存中的存储顺序为:同Dev C++
3个编译器都做到了数据对齐,但是后两个编译器显然没有VC聪明,让一个char型数据占4个字节,浪费内存。 |
在VC中,我们可以用pack预处理指令来禁止对齐处理,例如,下面的代码将使得结构尺寸更加紧凑,不会出现对齐到4字节问题。
#pragma pack(1)
struct astruct
{
char cvalue;
int ivalue;
};
#pragma pack()
除非你觉得有必要这样做,因为这样会降低程序性能。
|
阅读(1348) | 评论(0) | 转发(0) |