内存对齐机制

本文通过一个具体的代码示例,详细解释了内存对齐的机制,特别是在VC 6.0环境下,如何查看内存分配的情况。文章指出,编译器会根据变量的字节数进行内存对齐,以提高处理器的访问效率。结构体中,编译器会以最大的变量字节数为基准进行内存分配。虽然这可能导致额外的内存占用,但从整体效率角度看是有益的。并推荐了几篇深入理解内存对齐的参考资料。
摘要由CSDN通过智能技术生成

我相信在网上已经有很多关于内存对齐机制的文章了,在这里,我只想通过一个小例子来阐明内存分配的现象

有这样的一段代码:

//: 内存对齐_2
#include <cstdio>

struct A {
  char   m1;  // 1
  double m2;  // 8
  int    m3;  // 4
};

int main() {
  A a = {'A', 0.2, 4};

  printf("sizeof(A) = %d\n", sizeof(A));
  printf("A.m1      = %ld\n", long(&a.m1));
  printf("A.m2      = %ld\n", long(&a.m2));
  printf("A.m3      = %ld\n", long(&a.m3));
  printf("-----------------\n\n");

  return 0;
} ///:~ 


至于地址为什么是递增的就不多做解释了(编译器压入栈的顺序有关),在 VC 6.0 下进行调试,为了了解 a.m1、a.m2、a.m3 在内存中的对齐情况,先找出 a.m1 的内存地址:


这里的 0x0012ff30 就是 a.m1 的内存地址了,再来看 a.m1、a.m2、a.m3 的内存对齐情况:


图中正是 0x0012ff30 内存布局情况,其中红色框子分别表示 a.m1、a.m2、a.m3(在 32 位机上面,char 占 1 个字节,int 占 4 个字节,double 占 8 个字节,1 字节 = 8 位,每 4 位以 16 进制形式表示),浅蓝色框子表示填充部分(padding):

在 0x0012ff30 地址先存放了 char 类型的 m1,占 1 个字节(2 位),接着就要存放 double 类型的 m2,因为 m2 需要占 8 个字节(在内存对齐机制中,为了减少处理器对内存的访问次数,通常编译器都会在编译阶段对齐字节,规则是变量的内存地址必须是该变量字节数的整数倍),因此,存放完 m1 以后还要填充 7 个字节长度的内存,这样 m1 总的大小就占了 8 个字节长度;存放完 m2 以后,m3 占 4 个字节,前两者共占了 16 个字节,m3 的内存地址满足其字节倍,是不是就不需要填充呢?

如图示,答案就在图上,不是的,考虑定义结构体数组 A a[] = {0}; 编译器为了确保处理器总是一次就可以访问完一个变量,在分配内存的时候以结构体中“字节数最大的”变量进行分配,也就是满足 address + 8n;

尽管看来编译器花费了更多的内存去完成这件工作,但是对于整体的效率来说,却是获益了不少


不错的参考资料:

1. 《深入理解计算机系统》 Chapter 3 程序的机器级表示 3.9.3

2. 百度百科 http://baike.baidu.cn/view/4786260.htm

3. 内存对齐的原理,作用……  http://lc7cl.iteye.com/blog/1250481

4. C/C++内存分配与内存对齐全面探讨(比较详细,没看完)  http://blog.csdn.net/cuibo1123/article/details/2547442

5. 一篇讲对齐比较好的文章  http://old.uplook.cn/blog/10/109320/

6. C++内存对齐详细使用指南(不建议一开始看) http://developer.51cto.com/art/201002/183652.htm


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值