Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1204559
  • 博文数量: 232
  • 博客积分: 7563
  • 博客等级: 少将
  • 技术积分: 1930
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-21 11:17
文章分类

全部博文(232)

文章存档

2011年(17)

2010年(90)

2009年(66)

2008年(59)

分类:

2010-10-07 11:49:02

数据对齐:是指数据所在的内存地址必须是该数据长度的整数倍。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) |
给主人留下些什么吧!~~