您的位置:首页 > 其它

内存对齐

2012-09-08 23:31 204 查看
在C中如下结构:

struct foo { char c1; short s; char c2; int i; };

假设结构成员在内存中紧凑排列,c1地址0,s地址应该是1,c2地址3,i地址4

c1 00000000
s 00000001
c2 00000003
i 00000004

但VC6 中

#include<stdio.h>

Struct foo { char c1; short s; char c2; int i; };

int main()

{ struct foo a;

printf("c1\t%p\ns\t%p\nc2\t%p\ni\t%p\n", (unsigned int)(void*)&a.c1 - (unsigned int)(void*)&a, (unsigned int)(void*)&a.s - (unsigned int)(void*)&a, (unsigned int)(void*)&a.c2 - (unsigned int)(void*)&a, (unsigned int)(void*)&a.i - (unsigned int)(void*)&a);

printf("sizeof(foo)=%d\n",sizeof(foo)); return 0;

}

c1 00000000
s 00000002
c2 00000004
i 00000008

这就是内存对齐而导致的问题

为什么会有内存对齐

以下内容节选自《Intel Architecture 32 Manual》。
字,双字,和四字在自然边界上不需要在内存中对齐。(对字,双字,和四字来说,自然边界分别是偶数地址,可以被4整除的地址,和可以被8整除的地址。)
无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。
一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问。

如果不在编码时指定内存对齐方式,由于不同平台有不同的默认对齐方式从而造成通讯时不同平台数据通信数据处理问题,需要注意
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: