windows 內存分配雜談

1.GlobalAlloc是win16留下來的函數,它調用HeapAlloc分配堆中的內存。在理想的win32環境下,我們不需要GlobalAlloc,但是實際上,我們還得保留從win16移植過來的許多代碼。在這些代碼中使用了“內存句柄”(HGLOBAL)參數而不是32位的內存地址。  
            GlobalAlloc根據其屬性參數做兩件不同的事情。如果參數指定了GMEM_FIXED,則GlobalAlloc簡單調用HeapAlloc,把返回地址作爲一個32位HGLOBAL值;如果參數指定了GMEM_MOVEABLE,則返回的HGLOBAL值是一個指向進程裏句柄表中某一項入口的指針,該入口包含指向實際HeapAlloc  
  分配的內存的指針。  
            從本質上,如果我們不調用GlobalReAlloc函數,我們就可以用HeapAlloc代替GlobalAlloc。 

2.GlobalAlloc    函數

GlobalAlloc                                                                    
●    說明

該函數用於從全局堆中分配出內存供程序使用。

●    原型

HGLOBAL GlobalAlloc(UINT uFlags, //allocation attributes

                         SIZE_T dwBytes //number of bytes to allocate);

●    參數

uFlags:決定如何分配內存,如果爲零,則定義爲GMEM_FIXED。表7-2是GlobalAlloc標記的一覽表。

表7-2  GlobalAlloc標記

參    數 含    義
 
GHND GMEM_MOVEABLE和GMEM_ZEROINIT的組合
GMEM_FIXED 分配固定內存,返回值是一個指針
GMEM_MOVEABLE 分配活動內存,在Win32中,內存塊不能在物理內存中移動,但能在默認的堆中移動。返回值是內存對象的句
柄,用函數GlobalLock可將句柄轉化爲指針
GMEM_ZEROINIT 將內存內容初始化爲零
GPTR GMEM_FIXED和GMEM_ZEROINIT的組合

DwBytes:指定要分配的字節數。

●    返回值

如果函數調用成功則返回一個全局句柄,否則返回NULL。

例如,HGLOBAL hMem = GlobalAlloc(GHND, 27 );的意義是在全局堆中分配長爲27個字節和初始化爲零的內存塊,該內存塊是活動內存。


/////////////////////////////////////////////////////////////////////////////

 對全局內存對象進行加鎖:

LPVOID GlobalLock( HGLOBAL hMem);

   參數hMem是全局內存塊的句柄。函數調用成功,返回指向內存塊首地址的指針,否則返回NULL。可以與上一個函數GlobalAlloc進行由指針和句柄的轉化。

   對全局內存對象進行解鎖,每一次使鎖定計數減少1:

BOOL GlobalUnlock( GLOBAL hMem);

3.LOCALALLOC和GLOBALLOC有什麼區別? 全局內存和局部內存有什麼區別?

在16位Windows中是有區別的,因爲在16位windows用一個全局堆和局部堆來管理內存,每一個應用程序或dll裝入內存時,代碼段被裝入全局堆,而系統又爲每個實例從全局堆中分配了一個64kb的數據段作爲該實例的局部堆,用來存放應用程序的堆棧和所有全局或靜態變量。而LocalAlloc/GlobalAlloc就是分別用於在局部堆或全局堆中分配內存。  
  由於每個進程的局部堆很小,所以在局部堆中分配內存會受到空間的限制。但這個堆是每個進程私有的,相對而言分配數據較安全,數據訪問出錯不至於影響到整個系統。  
  而在全局堆中分配的內存是爲各個進程共享的,每個進程只要擁有這個內存塊的句柄都可以訪問這塊內存,但是每個全局內存空間需要額外的內存開銷,造成分配浪費。而且一旦發生嚴重錯誤,可能會影響到整個系統的穩定。  
  不過在Win32中,每個進程都只擁有一個省缺的私有堆,它只能被當前進程訪問。應用程序也不可能直接訪問系統內存。所以在Win32中全局堆和局部堆都指向進程的省缺堆。用LocalAlloc/GlobalAlloc分配內存沒有任何區別。甚至LocalAlloc分配的內存可以被GlobalFree釋放掉。所以在Win32下編程,無需注意Local和Global的區別,一般的內存分配都等效於HeapAlloc(GetProcessHeap(),...).
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章