1. 程式人生 > >Windows核心程式設計基礎之記憶體的分配與釋放

Windows核心程式設計基礎之記憶體的分配與釋放

       記憶體洩漏是C語言中一個臭名昭著的問題。但是作為核心開發者,讀者將有必要自己來面對它。在傳統的C語言中,分配記憶體常常使用的函式是:malloc,這個函式的使用非常簡單,傳入長度引數就得到記憶體空間。在驅動中使用記憶體分配,這個函式不再有效。驅動中分配記憶體,最常用的是呼叫ExAllocatePoolWithTag,其他的方法在本章範圍內全部忽略。回憶前一節關於字串處理的情況。一個字串被複制到另一個字串的時候,最好根據源字串空間長度來分配目標字串的長度。下面的例子,是一個字串 src 拷貝到字串 dst。

//--定義一個記憶體分配標記,
#define MEM_TAG 'MyTt'
//--目標字串,接下來它需要分配空間
UNICODE_STRING dst = {0};
//--分配空間給目標字串。根據源字串的長度
dst.Buffer = 
(PWCHAR)ExAllocatePoolWithTag(NonpagePool, src->Length, MEM_TAG);
if (NULL == dst.Buffer)
{
	//--錯誤處理
	status = STATUS_INSUFFICIENT_RESOURES;
	........
}
dst.Length = dst.MaximumLength = src->Length;
status = RtlCopyUnicodeString(&dst, &src);
ASSERT(status == STATUS_SUCCESS);
    ExAllocPoolWithTag 的第一個引數,NompagePool 表明分配的記憶體是鎖定記憶體。這些記憶體永遠真實存在於實體記憶體上,不會被分頁交換到硬碟上去。第二個引數是長度。第三個引數是所謂的"記憶體分配標記"。

     記憶體分配標記用於檢測記憶體洩漏。想象一下,我們根據佔用越來越多的記憶體的分配標記,就能大概知道洩漏的來源。一般每個驅動程式頂一個自己的記憶體標記,也可以在每個模組中定義單獨的記憶體標記。記憶體標記是隨意的32位數字,即使衝突也不會有什麼問題。

    注意,記憶體中最常見的分配存的方法是呼叫 ExAllocatePoolWithTag

    此外也可以分配可分頁記憶體,使用PagePool即可。

    ExAllocatePoolWithTag分配的記憶體可以使用ExFreePool來釋放,如果不釋放,則永遠洩漏,並不像使用者程序關閉後自動釋放所有分配的空間。即使驅動程式動態解除安裝,也不能釋放空間,唯一的辦法是重啟計算機。

    ExFreePool 只需要提供所釋放的指標即可。舉例如下:

ExFreePool(dst.Buffer);
dst.Buffer = NULL;
dst.Length = dst.MaximumLength = 0;
    ExFreePool 不能用來釋放一個棧空間的指標,否則系統立刻崩潰。像以下的程式碼:
UNICODE_STRING src = RTL_CONST_STRING(L"my source string");
ExFreePool(src.Buffer);
    上面的程式碼會導致立刻藍屏,所以請務必保持ExAllocatePoolWithTag 和 ExFreePool的成對關係。

                          ------------------------------------------摘自<[天書夜讀-從彙編到Windows核心程式設計]>

------------------------ 微笑  接著上次的 照片秀  -----------------------


-----繼續 堅持模仿 30 年, 耶。。 進行中.....