[ZZ]windows堆管理的函數

來源:互聯網
上載者:User

使用者使用記憶體配置函數分配的記憶體都位於堆中,所以使用堆管理函數對記憶體進行分配,釋放等是最直接的方式.
windows系統中,每個進程都有自己的堆,每個進程堆數量也不同,windows系統中所謂的堆(Heap)並不是記憶體塊,
而是一種記憶體管理對象,是一種記憶體組織的形式.進程可以從屬於自己的堆上分配記憶體和釋放記憶體.

堆是一種記憶體管理對象,一個進程有若干該堆,在分配記憶體前需要指定從哪個堆上進行分配.堆的控制代碼唯一標識
了一個堆.獲得堆控制代碼兩種方式:
1.擷取在進程中已經建立好的堆
2.進程自己再建立堆.有了堆的控制代碼就可在上面分配記憶體了.
在堆中分配記憶體,使用者不用考慮分頁,對齊,記憶體塊可以任意大小.

1.HeapCreate
為進程建立新堆,請求分配虛擬記憶體分頁
HANDLE HeapCreate(
DWORD flOptions,
SIZE_T dwInitialSize,
SIZE_T dwMaximumSize
);
flOptions:輸入參數,建立堆選項
HEAP_CREATE_ENABLE_EXECUTE 分配的記憶體允許用於代碼執行
HEAP_GENERATE_EXCEPTIONS    如果分析記憶體失敗會產生異常,而不是返回NULL
HEAP_NO_SERIALIZE           不進行連續儲存
dwInitialSize 堆的初始化大小(位元組),0,系統自動分配一個記憶體頁大小
dwMaximumSize 堆大小最大值,0表示向上增長
失敗返回NULL

2.GetProcessHeap
擷取當前進程中的一個堆,返回堆控制代碼
HANDLE GetProcessHeap(void);
失敗返回NULL

3.GetProcessHeaps
獲得進程中的所有堆,包括堆的數量和堆的控制代碼
DWORD GetProcessHeaps(
DWORD NumberOfHeaps,
PHANDLE ProcessHeaps
);
NumberOfHeaps:輸入參數,緩衝區ProcessHeap所能儲存的控制代碼個數.
ProcessHeaps:輸出參數,指向用於儲存進程中所有堆的控制代碼的記憶體塊,函數傳回值控制代碼值會在其中儲存.
傳回值:
DWORD類型的資料,進程中堆的個數.返回0,則失敗
傳回值大於NumberOfHeaps,說明進程中實際的堆數量大於NumberOfHeaps.用於儲存控制代碼值的記憶體地區太小,
ProcessHeaps指向的記憶體塊沒有控制代碼值。反之小於則ProcessHeaps儲存了所有堆的控制代碼值.

4.從指定堆上分配記憶體塊
LPVOID HeapAlloc(
HANDLE
hHeap,
DWORD
dwFlags,
SIZE_T dwBytes
);
hHeap:輸入參數,表明從此參數指定的堆上進行記憶體配置.
dwFlags:輸入參數,記憶體配置標誌
HEAP_GENERATE_EXCEPTIONS 如果分配錯誤則拋出異常,而不是返回NULL
         (STATUS_NO_MEMORY記憶體不足,STATUS_ACCESS_VIOLATIONC存取不合法)
HEAP_NO_SERIALIZE   不使用連續儲存
HEAP_ZERO_MEMORY      將分配的記憶體塊中的內容全部清零.
dwBytes:輸入參數,需要分配記憶體地區大小,以位元組為單位.
返回新分配的記憶體指標,失敗NULL

5.LPVOID HeapReAlloc(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpMem,
SIZE_T dwBytes
);
hHeap:輸入參數,表明從此參數指定的堆上進行記憶體配置.
dwFlags:輸入參數,記憶體配置標誌.
HEAP_GENERATE_EXCEPTIONS 如果分配錯誤則拋出異常,而不是返回NULL
         (STATUS_NO_MEMORY記憶體不足,STATUS_ACCESS_VIOLATIONC存取不合法)
HEAP_NO_SERIALIZE   不使用連續儲存
HEAP_ZERO_MEMORY      與HeapAlloc中作用不同,設定此標誌,新增加的記憶體將被清零,原記憶體塊中資料不會變化.
HEAP_REALLOC_IN_PLACE_ONLY,
HEAP_REALLOC_IN_PLACE_ONLY表示重新分配記憶體的位置不要發生變化.
lpMem:輸入參數,原記憶體塊的地址.
dwBytes:輸入參數,記憶體塊大小調整後的值,可以比原來大,也可以小.
傳回值:返回成功,返回LPVOID類型資料,是大小調整後記憶體塊的指標.

6.GetSystemInfo
擷取系統資訊,包括OEM資訊,記憶體塊大小,記憶體配置粒度,處理器資訊,記憶體空間最大值和最小值等.
void GetSystemInfo(
LPSYSTEM_INFO lpSystemInfo
);
lpSystemInfo:輸出函數,指向SYSTEM_INFO結構指標,儲存擷取資訊.

7.HeapSize用於擷取指定堆大小,以位元組為單位返回堆大小資訊
SIZE_T HeapSize(
HANDLE hHeap,
DWORD dwFlags,
LPCVOID lpMem
);
hHeap:輸入參數,需要獲得大小的記憶體塊所在的堆的控制代碼.
dwFlags:輸入參數,記憶體塊標誌,可以是HEAP_NO_SERIALIZE
lpMem:所需要擷取大小的記憶體塊指標.
返回SIZE_T記憶體塊大小,失敗為-1.

8.HeapFree
釋放HeapAlloc和HeapReAlloc所分配的記憶體,函數原型如下:
BOOL HeapFree(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpMem
);
hHeap:輸入參數,記憶體塊所在的堆,需要使用HeapAlloc和HeapReAlloc分配記憶體同樣的堆.
dwFlags:輸入參數,記憶體塊標誌,可以設定為HEAP_NO_SERIALIZE
lpMem:輸入參數,所需釋放的記憶體塊指標.

9.HeapDestroy
銷毀由HeapCreate建立的堆,函數原型如下:
BOOL HeapDestroy(
HANDLE hHeap
);
hHeap:輸入參數,所需銷毀堆的控制代碼
返回BOOL值,表示是否成功.

code:

/* 標頭檔 */
#include <windows.h>
#include <stdio.h>

/*************************************
* DWORD PrintHeapSize(HANDLE hHeap,LPVOID
lpMem)
* 功能 擷取堆的大小並列印出來
*
* 參數 HANDLE hHeap,堆控制代碼
*   LPVOID lpMem,記憶體位址指標
*
* 傳回值 0代表執行完成,1代碼發生錯誤。
**************************************/
DWORD PrintHeapSize(HANDLE hHeap,LPVOID
lpMem)
{
SIZE_T dwHeapSize;
dwHeapSize = HeapSize(hHeap,HEAP_NO_SERIALIZE,lpMem);
if(dwHeapSize == -1)
{
   printf("Get HeapSize error :%d",GetLastError());
   return 1;
}
printf("記憶體塊大小為:0x%x\n",dwHeapSize);
return 0;
}

/*************************************
* int main(int argc, PCHAR argv[])
* 功能 示範堆的使用
*
* 參數 argv[1]如果為“-s”那麼使用進程堆
*   argv[1]如果為“-a”那麼建立一個可變大小的堆
*   argv[1]如果為其他,那麼建立有最大大小的堆。
*
*
**************************************/
int main(int argc, PCHAR argv[])
{
SYSTEM_INFO si; //系統資訊
HANDLE hHeap; //堆控制代碼
LPVOID lpMem; //記憶體塊指標
LPVOID lpReAlloc; //記憶體塊大小調整後的指標
DWORD dwHeapSize; //堆記憶體埠大小
HANDLE hHeaps[24]; //用於儲存進程中所有的堆控制代碼
DWORD dwHeapNum; //進程中堆的數量\
//擷取系統資訊
GetSystemInfo(&si);
//將系統記憶體分頁大小,與記憶體配置粒度列印出來。
printf("系統記憶體頁大小: 0x%x\n系統記憶體配置粒度:0x%x\n",
   si.dwPageSize,si.dwAllocationGranularity);
//分析輸入參數,如果是“-a”建立一個最大為10個分頁大小的堆
if(argc == 2 && 0==lstrcmp(argv[1],"-a"))
{
   hHeap = HeapCreate(HEAP_NO_SERIALIZE,
    si.dwPageSize,si.dwPageSize*10);
   printf("建立堆,初始化大小為1頁,最大為10頁\n");
}
//如果輸入參數為“-s”使用進程初始化時已經存在的堆
else if(argc == 2 && 0==lstrcmp(argv[1],"-s"))
{
   hHeap = GetProcessHeap();
   printf("擷取系統已經存在的堆\n");
}
//如果輸入其他,建立一個可增長的堆
else
{
   hHeap = HeapCreate(HEAP_NO_SERIALIZE,0,0);
   printf("建立堆,初始化大小為1頁,大小可變\n");
}
//判斷堆是否建立/擷取成功
if(hHeap == NULL)
{
   printf("建立或擷取進程堆錯誤: %d",GetLastError());
   return 1;
}
//擷取將列印當前進程中一共有多少個堆,有沒有建立堆,值會不同
dwHeapNum = GetProcessHeaps(24,hHeaps);
if(dwHeapNum == 0)
{
   printf("GetProcessHeaps error: %d",GetLastError());
}
else
{
   printf("當前進程一共有%d個堆\n",dwHeapNum);
}
//在堆上分析記憶體,3個頁面大小
lpMem = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,si.dwPageSize*3);
if(lpMem == NULL)
{
   printf("HeapAlloc error: %d",GetLastError());
   return 1;
}
printf("在堆上成功分配記憶體,起始地址為:0x%x\n",lpMem);
//列印當前堆記憶體塊的大小
PrintHeapSize(hHeap,lpMem);
//再分配記憶體,調整記憶體的大小為11個分頁大小,
//如果使用第一種方法建立堆,這裡會出錯
lpReAlloc = HeapReAlloc(hHeap, HEAP_ZERO_MEMORY,
lpMem, si.dwPageSize*11);
if(lpReAlloc == NULL)
{
   printf("HeapReAlloc error: %d",GetLastError());
   return 1;
}
printf("在堆上再分配記憶體,地址為:0x%x,原地址:0x%x\n",lpReAlloc,lpMem);
//列印調整大小後的堆記憶體塊大小
PrintHeapSize(hHeap,lpReAlloc);

//釋放記憶體
if(!HeapFree( hHeap, HEAP_NO_SERIALIZE, lpReAlloc))
{
   printf("HeapFree error: %d",GetLastError());
   return 1;
}
printf("釋放記憶體成功\n");
//如果建立了堆,銷毀堆。
if(argc != 2 || 0!=lstrcmp(argv[1],"-s"))
{
   printf("銷毀HeapCreate建立的堆\n");
   if(!HeapDestroy(hHeap))
   {
    printf("HeapDestroy error: %d",GetLastError());
    return 1;
   }
   printf("銷毀堆成功\n");
}
return 0;
}

原連結為:http://hi.baidu.com/bodogbo/blog/item/c2b1663bf4c846ff3b87ce5e.html

疑問如下:lpmem用途是?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.