Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc) 关于内存的5个函数(malloc,VirtualAlloc,GlobalAlloc,L

Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc)html

来源:http://blog.csdn.net/chunyexiyu/article/details/39320805算法

内存分配函数/内存管理API

参考:编程

Windows MSDNwindows

http://msdn.microsoft.com/en-us/library/aa908768.aspx安全

 

附助资料:数据结构

http://blog.csdn.net/susubuhui/article/details/7315094less

http://wenku.baidu.com/link?url=yxgCWePPV1kFaIUciEspYgm34wNAnMLDoduBlfsEEo-mW0JFRVEOkixomUjPatqw_jOXZcqQ1CLoeBSZqLuse1KiyHD6ysZTMIzLy_sPgPS函数

http://blog.csdn.net/sharecode/article/details/7464915工具

 

Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu  转载请标明来源 post

 

 

 

对于Windows来讲,提供了一些API接口进行Heap内存管理,是独立于C++/C程序以外的,仅用于Windows平台的API。

 

大概分为下面几组接口:

 

老的Heap接口GlobalXXX(新程序不建议使用,这些函数存在主要是兼容之前写的程序):

GlobalAlloc/GlobalRelloc/GlobalFree:从Heap申请一块内存

GlobalLock/GlobalUnlock: 从GlobalAlloc的内存中申请一段内存

函数参数:

 

 

新的Heap接口HeapXXX:

HeapCreate/HeapDestroy/GetProcessHeap:从Heap中申请一块内存

HeapAlloc/HeapRelloc/HeapFree/HeapSize:从HeapCreate的内存中申请一段内存

HeapValidatee:查询Heap或Alloc的信息

 

当前进程Heap内存接口LocalXXX:

LocalAlloc/LocalReAlloc/LocalFree/LocalSize:从当前Heap的内存中申请一段内存,至关于从HeapAlloc从GetProcessHeap中申请内存。

 

虚拟地址内存接口: VirtualXXX

VirtualAlloc/VirtualFree/ VirtualProtect/VirtualQuery:从进程堆中申请页面内存数据。一般用于申请一段大内存,最少申请一页。reserves or commits a region of pages。

关于这一块详细请参考:http://blog.csdn.net/sharecode/article/details/7464915

 

malloc,new,VirtualAlloc,HeapAlloc这几组的执行效率:

参考:http://blog.csdn.net/susubuhui/article/details/7315094

分配大内存的时候 VirtualAlloc才能体现出优点,申请小内存时比较慢。

至于小块内存那就是HeapAlloc > malloc > new,由于都是调用HeapAlloc,直接使用HeapAlloc要快不少。

 

扩展的新接口xxxEx(不是全部版本都支持)

以Ex结尾,例如VitualAllocEx,能够指定process handle,从而从其它运行进程空间申请一段内存。

 

函数说明:

HeapCreate:

从内存区申请一段内存做为堆。This function reserves memory from the shared memory area.

HeapDestroy:

删除HeapCreate建立的堆。This function destroys the specified heap object.

GetProcessHeap:

获取当前进程的堆Handle。注意这个不能使用Destroy删除。This function obtains a handle to the heap of the calling process. This handle can then be used in calls to the HeapAlloc,HeapReAlloc,HeapFree, andHeapSize functions.

 

HeapAlloc:

从指定堆申请一段内存,该段内存是不被移动的。This function allocates a block of memory from a heap. The allocated memory is not movable.

HeapReAlloc:

从指定堆从新申请一段内存。This function reallocates a block of memory from a heap. The allocated memory is not movable.

HeapFree:

释入HeapAlloc或HeapReAlloc申请的内存。This function frees a memory block from a heap. The memory block was allocated by the HeapAlloc or theHeapReAllocfunction.

HeapSize:

根据Handle、内存开始地址,查询一段HeapAlloc内存的大小。This function returns the size, in bytes, of a memory block allocated from a heap by the HeapAllocorHeapReAlloc function.

 

HeapValidate:

检查Heap Handle或Heap Handle下申请的内存是否有效。

This function validates the specified heap. HeapValidate scans all the memory blocks in the heap and verifies that the heap control structures maintained by the heap manager are in a consistent state. The HeapValidate function can also be used to validate a single memory block within a specified heap without checking the validity of the entire heap.

 

LocalAlloc/LocalReAlloc/LocalFree/LocalSize:

从当前进程Heap中进行操做。该组函数至关于HeapXXX指定Heap Handle为当前进程Handle。函数参考HeapAlloc / HeapReAlloc/ HeapFree/ HeapSize做用。

LocalAlloc : This function allocates the specified number of bytes from the heap.

In the linear Windows Embedded CE API environment, there is no difference between the local heap and the global heap.LocalAlloc is equivalent toHeapAlloc(GetProcessHeap, …).

 

VirtualAlloc/VirtualFree/ VirtualProtect/VirtualQuery:

从当前进程空间中申请页面空间数据,最少申请一页。

The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

To allocate memory in the address space of another process, use theVirtualAllocEx function.

 

关于内存的5个函数(malloc,VirtualAlloc,GlobalAlloc,LocalAlloc,HeapAlloc)

来源:http://www.cnblogs.com/Madridspark/p/5778433.html

VirtualAlloc

  该函数的功能是在调用进程的虚地址空间,预约或者提交一部分页,若是用于内存分配的话,而且分配类型未指定MEM_RESET,则系统将自动设置为0

  一次分配 1PAGE 以上的 RAM. 每次分配都是 PAGE 的整数倍. 你不会想为了分配 1 个 BYTE 的空间而浪费剩下的 4095 字节. OK, 你能够本身写算法, 多分配几 PAGE. 而后每次分配少许数据时就从那几 PAGE 中划分出来. KERNEL32 提供了一个解决办法, 用 HeapAlloc/GlobalAlloc 分配 RAM. 这样, KERNEL32 帮助完成分配动做, 而且尽可能在减小用于跟踪空闲区域和已占用区域消耗的数据结构.

 

GlobalAlloc 和 LocalAlloc

  从全局堆中分配出内存供程序使用

   都是 Windows 系统提供的内存分配函数, 他们的区别在于 16BIT 代码时代, 那时没有不一样的进程内存空间, GlobalAlloc 是在全局的, 公用的远堆上分配; LocalAlloc 则在任务本身的近堆上分配. 在 Win32 平台下这两个函数是彻底相同的, 都是在进程本身的内存空间中分配, Lock 以后的结果是普通指针(32位近指针). 

 

HeapAlloc

  从堆上分配一块内存,且分配的内存是不可移动的(即若是没有连续的空间能知足分配的大小,程序不能将其余零散的空间利用起来,从而致使分配失败),该分配方法是从一指定地址开始分配,而不像GloabalAlloc是从全局堆上分配,这个有多是全局,也有多是局部。

  HeapCreate 就已经完成了建立堆的操做. HeapAlloc, HeapReAlloc 和 HeapFree 都是从这个堆中分配, 释放内存的函数. 也就是说, Windows 系统其实已经为咱们提供了完整的一套使用本身的局部堆的操做, 不过没有看到指定分配策略的方法. 根据编译器提供的源代码来 看, VC 中的 malloc, realloc 和 free 等函数主要功能就是用这几个 API 函数来实现的, 而 BC 中的实现至关复杂, 彷佛是维护了一套本身的逻辑. 听说 BC 的内存分配比 VC 快, 大概是这个缘由. 

  好久之前也有个产品叫作 WINDOWS. 那时候的 WINDOWS 是 16BIT 的, 地址空间有些紧俏, 有钱不够, 还须要粮票肉票才能拿到. 你已经调用 GlobalAlloc 和已经出钱的性质同样. GlobalAlloc 还不够, 有时候须要 GlocalLock 才能肯定你的东西确实能够拿到手, 否则你的指针会非法, 被充公, 你的应用会被杀头. 扯远了. 后来 OS 进化了, 以为能够取消粮票肉票, 可是你必须用新版钞票才行. 那就是 HeapAlloc. 只要市场上的 RAM 数量没问题, 你的 HeapAlloc 没问题, 那就总能拿到东西. 可是, 你总不能说有了 2000 版的钞票, 那 80 版的立刻做废啊, 那 GlobalAlloc 也只好继续流通下去. 至于能够流通到何时, 没人知道.       // 这比喻至关经典啊!!!

  new 与它们的区别未免太大, 由于与 C++ 的构造函数和异常机制有关. 通常编译器中的 new 都是用 malloc 来分配内存的. 用 malloc 与其它两个函数比较应该更合理. 通常 malloc 的实现并非从系统的堆中分配的, 而是从编译器链接的运行库本身管理的堆中, 在 Win32 平台上的开发工具的编译结果中, 一般是用 HeapCreate 建立一个堆, 用 HeapAlloc 和 HeapRealloc 维护堆的空间增加, 在最后用 HeapDestroy 删除堆. 而在用 malloc 分配, 用 free 释放时则由运行库的代码负责从这个堆中分配空间和向这个堆中归还空间, 并维护这个堆中的数据结构. 因为 malloc 堆的管理是由运行库本身管理的, 所在当咱们使用静态运行库时, 若是在一个 DLL 中用 malloc 分配了内存而在另外一个 DLL 中用 free 去释放它, 一般都会产生问题. 这是由于每一个DLL都链接了一份运行库的代码, 从而也都有一个本身的局部堆, 而在用 free 释放时它会假设这块内存是在本身的堆中分配的, 从而致使错误. 而经过 GlobalAlloc 和 LocalAlloc 分配的内存不存在这个问题.

 

 

HeapAlloc、VirtualAlloc、GlobalAlloc和LocalAlloc 

来源:http://blog.chinaunix.net/uid-26111972-id-2239571.html

1. HeapAlloc:

MSDN上的解释为:HeapALloc是从堆上分配一块内存,且分配的内存是不可移动的(即若是没有连续的空间能知足分配的大小,程序不能将其余零散的空间利用起来,从而致使分配失败),该分配方法是从一指定地址开始分配,而不像GloabalAlloc是从全局堆上分配,这个有多是全局,也有多是局部。函数原型为:
LPVOID
HeapAlloc(
    HANDLE hHeap,
    DWORD dwFlags,
   SIZE_T dwBytes
    );
hHeap是进程堆内存开始位置。
dwFlags是分配堆内存的标志。包括HEAP_ZERO_MEMORY,即便分配的空间清零。
dwBytes是分配堆内存的大小。
其对应的释放空间函数为HeapFree。
2. GlobalAlloc:该函数用于从全局堆中分配出内存供程序使用,函数原型为:
HGLOBAL GlobalAlloc(
UINT uFlags,
SIZE_T dwBytes
);
uFlags参数含义
GHND   GMEM_MOVEABLE和GMEM_ZEROINIT的组合
GMEM_FIXED   分配固定内存,返回值是一个指针
GMEM_MOVEABLE   分配活动内存,在Win32中,内存块不能在物理内存中移动,但能在默认的堆中移动。返回值是内存对象的句柄,用函数GlobalLock可将句柄转化为指针
GMEM_ZEROINIT   将内存内容初始化为零
GPTR   GMEM_FIXED和GMEM_ZEROINIT的组合
通常状况下咱们在编程的时候,给应用程序分配的内存都是能够移动的或者是能够丢弃的,这样能使有限的内存资源充分利用,因此,在某一个时候咱们分配的那块内存的地址是不肯定的,由于他是能够移动的,因此得先锁定那块内存块,这儿应用程序须要调用API函数GlobalLock函数来锁定句柄。以下: lpMem=GlobalLock(hMem); 这样应用程序才能存取这块内存。因此咱们在使用GlobalAllock时,一般搭配使用GlobalLock,固然在不使用内存时,必定记得使用 GlobalUnlock,不然被锁定的内存块一直不能被其余变量使用。
GlobalAlloc对应的释放空间的函数为GlobalFree。
3. LocalAlloc:该函数用于从局部堆中分配内存供程序使用,函数原型为:
HLOCAL LocalAlloc(
UINT uFlags,
SIZE_T uBytes
);
参数同GlobalAlloc。
在 16位Windows中
LocalAlloc和GlobalAlloc是有区别的,由于在16位windows用一个全局堆和局部堆来管理内存,每个应用程序或dll装入内存时,代码段被装入全局堆,而系统又为每一个实例从全局堆中分配了一个64kb的数据段做为该实例的局部堆,用来存放应用程序的堆栈和全部全局或静态变量。而 LocalAlloc/GlobalAlloc就是分别用于在局部堆或全局堆中分配内存。
     因为每一个进程的局部堆很小,因此在局部堆中分配内存会受到空间的限制。但这个堆是每一个进程私有的,相对而言分配数据较安全,数据访问出错不至于影响到整个系统。
     而在全局堆中分配的内存是为各个进程共享的,每一个进程只要拥有这个内存块的句柄均可以访问这块内存,可是每一个全局内存空间须要额外的内存开销,形成分配浪费。并且一旦发生严重错误,可能会影响到整个系统的稳定。

    不过在Win32中,每一个进程都只拥有一个省缺的私有堆,它只能被当前进程访问。应用程序也不可能直接访问系统内存。因此在Win32中全局堆和局部堆都指向进程的省缺堆。用LocalAlloc/GlobalAlloc分配内存没有任何区别。甚至LocalAlloc分配的内存能够被 GlobalFree释放掉。因此在Win32下编程,无需注意Local和Global的区别,通常的内存分配都等效于 HeapAlloc(GetProcessHeap(),...)。LocalAlloc对应的释放函数为LockFree。4. VirtualAlloc:该函数的功能是在调用进程的虚地址空间,预约或者提交一部分页,若是用于内存分配的话,而且分配类型未指定MEM_RESET,则系统将自动设置为0;其函数原型:LPVOID VirtualAlloc(LPVOID lpAddress, // region to reserve or commitSIZE_T dwSize, // size of regionDWORD flAllocationType, // type of allocationDWORD flProtect // type of access protection);VirtualAlloc 能够经过并行屡次调用提交一个区域的部分或所有来保留一个大的内存区域。多重调用提交同一块区域不会引发失败。这使得一个应用程序保留内存后能够随意提交将被写的页。当这种方式不在有效的时候,它会释放应用程序经过检测被保留页的状态看它是否在提交调用以前已经被提交。VirtualAlloc对应的释放函数为VirtualFree。5.Malloc:malloc 与free是C++/C语言的标准库函数,可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用 malloc/free没法知足动态对象的要求。对象在建立的同时要自动执行构造函数,对象在消亡以前要自动执行析构函数。因为malloc/free是库函数而不是运算符,不在编译器控制权限以内,不可以把执行构造函数和析构函数的任务强加于malloc/free。6.New:new/delete 是C++的运算符。可用于申请动态内存和释放内存。C++语言须要一个能完成动态内存分配和初始化工做的运算符new,以一个能完成清理与释放内存工做的运算符delete。注意new/delete不是库函数。C++程序常常要调用C函数,而C程序只能用malloc /free管理动态内存。new 是个操做符,和什么"+","-","="...有同样的地位.        malloc是个分配内存的函数,供你调用的.        new是保留字,不须要头文件支持.        malloc须要头文件库函数支持.new 创建的是一个对象,        malloc分配的是一块内存.        new创建的对象你能够把它当成一个普通的对象,用成员函数访问,不要直接访问它的地址空间        malloc分配的是一块内存区域,就用指针访问好了,并且还能够在里面移动指针.内存泄漏对于malloc或者new均可以检查出来的,区别在于new能够指明是那个文件的那一行,而malloc没有这些信息。new能够认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针。
相关文章
相关标签/搜索