使用windows内存-堆内存

1 堆内存的特点

    一般分配小数据内存,一般小于1M数据使用堆内存分配。 一般程序执行后,会有一个默认堆,这个堆

的大小一般为1M,由系统维护,程序员无法销毁默认堆。还有一个CRT堆,malloc和new就是在CRT堆分配内存,

一个程序可以多个堆。通过堆内存管理器来管理堆中的内存。可以使用HeapCreate创建自定义堆。内存分配速度比VirtualAlloc慢。

    New和malloc的使用不再讲解,下面直接讲解自定义堆的使用

  2 自定义堆内存的使用

   2.1 创建堆

     HANDLE HeapCreate(

     DWORD flOptions,//创建标示

     DWORD dwInitialSize,  //初始化大小

     DWORD dwMaximumSize ); //最大大小

   2.2 分配内存

     LPVOID HeapAlloc(

     HANDLE hHeap,  //堆的句柄

     DWORD dwFlags, //分配标示

     DWORD dwBytes );  //分配大小

    2.3 使用内存

   2.4 释放内存

     BOOL HeapFree(

     HANDLE hHeap,  //堆的句柄

     DWORD dwFlags, //释放标示

     LPVOID lpMem );  //释放的地址

   2.5 释放堆

     BOOL HeapDestroy(

     HANDLE hHeap );  //堆的句柄

 

  3 malloc/HeapAlloc/VirtualAlloc的关系

   在windows平台上,malloc内部调用HeapAlloc, HeapAlloc内部调用的VirtualAlloc。

   malloc分配内存:

     例如100字节

    | 内存头 | 100字节 | 4字节尾部标示 |

     所有使用malloc分配的内存,会使用这个内存头构成链表.所有malloc的内存都在这个链表上,通过这个链表来管理

很多人都对VirtualAllocmalloc new的区别不是很清楚,我也一样。今天搜索下了,发现这句话说的很清楚了:

 

    VirtualAlloc要进入内核模式,算法特复杂,比较慢,而且分配粒度是4k,用来分配小块内存很浪费

 

    malloc先用HeapAlloc(内部调用VirtualAlloc)弄一大块内存,后面在堆上分配时就不用进入内核模式,算法也简单些,而且分配粒度比较小

 

    VirtualAlloc只能分配4KB为单位的页面,适合大型数据或者内存映射文件等用途。而堆的申请分配就没有这个限制,更为灵活。

 

有的人嫌malloc还不够精简,于是又在堆上面开辟自己的内存池,更加轻量级

    

 

 

Malloc和heapalloc区别

malloc是在CRT的内存堆上分配的,这个堆的存在一般来说你是不会关心的

HeapAlloc则不同,你需要给它指定你想从哪个堆上分配,而这个堆是从HeapCreate创建出来的

HeapAlloc大多是用于自己管理堆的情况

malloc可以移植是因为在不同的操作系统上有各自的实现,而所有平台上就叫这个名字。比如在Widnows上,VC中调用malloc时,其实在malloc内部就是通过调用Windows API HeapAlloc在指定的堆上分配内存的,而C++ Builder中调用malloc,其实在malloc内部调用AirtualAlloc,所以不同的编译器也有不同的实现,

但都是以OS的API为基础的,所以你的问题的回答其实是调用与被调用的关系.

malloc(); 和 HeapAlloc(); 都是从堆中分配相应的内存

不同的是一个是c run time的函数一个是windows系统的函数

这么说你应该可以想到对于windows程序来说使用HeapAlloc();会比malloc();效率稍稍高一些

实际也是这样的其实有许多crt的函数 ms在win中都提供了相似功能的系统函数

HeapAlloc和malloc的区别在于他们属于不同的函数库。前者属于平台sdk,后者则是标准库。

两个函数在分配空间时都是分配在堆中,实现结果也有细微差别。如malloc分配的实际空间可能比你指定的多些

 

  4 堆的信息查看

   GetProcessHeap 当前进程默认堆的句柄

GetProcessHeaps 当前进程所有堆的句柄

 

 

 

 

实例代码:

 

// WinHeap.cpp :Defines the entry point for the console application.
//
 
#include"stdafx.h"
#include"stdlib.h"
#include"windows.h"
 
void HeapInfo( )
{        //默认堆的句柄
         HANDLE hHeap = GetProcessHeap();
         printf( "Default Heap: %p\n",hHeap );
         //所有的堆的句柄
         HANDLE hHeaps[256] = { 0 };
         DWORD nCount =
                   GetProcessHeaps( 256, hHeaps);
         printf( "All Heap: %d\n",nCount );
         for( DWORD nIndex=0; nIndex<nCount;nIndex++ )
         {
                   printf( "\t%d:%p\n", nIndex+1,
                            hHeaps[nIndex] );
         }
}
 
void Heap( )
{
         HeapInfo( );
 
         //创建堆
         HANDLE hHeap = HeapCreate(
                   HEAP_GENERATE_EXCEPTIONS,
                   1024 * 1024, 0 );
         printf( "HeapCreate: %p\n",hHeap );
 
         HeapInfo( );
 
         //内存分配
         CHAR * pszBuf = ( CHAR * )
                   HeapAlloc( hHeap,HEAP_ZERO_MEMORY, 100 );
         printf( "HeapAlloc: %p\n",pszBuf );
 
         strcpy( pszBuf, "hello Heap");
         printf( "%s\n", pszBuf );
 
         //内存释放
         HeapFree( hHeap, 0, pszBuf );
 
         //释放堆
         HeapDestroy( hHeap );
 
         HeapInfo( );
}
 
int main(intargc, char* argv[])
{
         CHAR * pszBuf = (CHAR *)malloc( 1024 );
 
         Heap( );
         return 0;
}


 

你可能感兴趣的:(new,内存管理,堆内存,HeapAlloc)