HeapAlloc和GlobalAlloc以及VirtualAlloc三者之间的关系

VirtualAlloc一次分配1PAGE以上的RAM. 每次分配都是PAGE的整数倍. 你不会想为了分配1个BYTE的空间而浪费剩下的4095字节. OK. 你可以自己写算法,多分配几PAGE. 然后每次分配少量数据时就从那几PAGE中划分出来. 什么? 你笨到不会写分配算法? 好巴 KERNEL32给你一个解决办法. 用HeapAlloc/GlobalAlloc分配RAM. 这样, KERNEL32帮你完成分配动作, 并且尽量在减少用于跟踪空闲区域和已占用区域消耗的数据结构.       很久以前也有个产品叫做WINDOWS. 那时候的WINDOWS是16BIT的. 地址空间有些紧俏. 有钱不够. 还需要粮票肉票才能拿到. 你已经调用GlobalAlloc和已经出钱的性质一样. GlobalAlloc还不够. 有时候需要GlocalLock才能确定你的东西确实可以拿到手.不然你的指针会非法. 被充公. 你的应用会被杀头. 扯远了. 后来OS进化了. 觉得可以取消粮票肉票. 但是你必须用新版钞票才行. 那就是HeapAlloc. 只要市场上的RAM数量没问题 . 你的HeapAlloc没问题. 那就总能拿到东西. 但是, 你总不能说有了2000版的钞票, 那80版的马上作废啊. 那GlobalAlloc也只好继续流通下去. 至于可以流通到什么时候. 没人知道.

GlobalAlloc和LocalAlloc都是Windows系统提供的内存分配函数,他们的区别源于16位代码时代,那时没有不同的进程内存 空间,GlobalAlloc是在全局的、公用的远堆上分配,LocalAlloc则在任务自己的近堆上分配。在Win32平台下这两个函数是完全相同 的,都是在进程自己的内存空间中分配,Lock之后的结果是普通指针(32位近指针)。           new与它们的区别未免太大,因为与C++的构造函数和异常机制有关。一般编译器中的new都是用malloc来分配内存的。用malloc与其它两 个函数比较应该更合理。一般malloc的实现并不是从系统的堆中分配的,而是从编译器连接的运行库自己管理的堆中,在Win32平台上的开发工具的编译 结果中,通常是用HeapCreate创建一个堆,用HeapAlloc和HeapRealloc维护堆的空间增长,在最后用HeapDestroy删除 堆。而在用malloc分配、用free释放时则由运行库的代码负责从这个堆中分配空间和向这个堆中归还空间,并维护这个堆中的数据结构。           由于malloc堆的管理是由运行库自己管理的,所在当我们使用静态运行库时,如果在一个DLL中用malloc分配了内存而在另一个DLL中用 free去释放它,通常都会产生问题,这是因为每个DLL都连接了一份运行库的代码,从而也都有一个自己的局部堆,而在用free释放时它会假设这块内存 是在自己的堆中分配的,从而导致错误。而通过GlobalAlloc和LocalAlloc分配的内存不存在这个问题。

HeapCreate就已经完成了创建堆的操作,HeapAlloc、HeapRealloc和HeapFree都是从这个堆中分配、释放内存的函 数。也就是说,Windows系统其实已经为我们提供了完整的一套使用自己的局部堆的操作,不过没有看到指定分配策略的方法。根据编译器提供的源代码来 看,VC中的malloc、realloc和free等函数主要功能就是用这几个API函数来实现的,而BC中的实现相当复杂,似乎是维护了一套自己的逻 辑。据说BC的内存分配比VC快,大概就是这个原因了


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fgh_555/archive/2008/06/18/2560774.aspx

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值