ZeroMemory
ZeroMemory
是一個宏,不是函數,它的定義如下:
#define ZeroMemory RtlZeroMemory
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
我們發現,這個 ZeroMemory
是 RtlZeroMemory
的宏定義,而 RtlZeroMemory
是一個有參宏,最終是通過調用C標準庫函數 memset
來實現的。
下面爲了方便,我們還是以函數原型的形式展示它的用法:
void ZeroMemory(
[in] PVOID Destination,
[in] SIZE_T Length
);
參數說明:
Desitination
:需要被填充0的內存塊的起始地址
Length
:需要被填充0的內存塊以字節爲單位計數的長度
注意事項:
不同語言可能提供了不同的語法用於將複雜變量初始化爲0,他們的具體行爲可能和 ZeroMemory
有所區別,因此在開發 Windows 應用程序最好總是使用 ZeroMemory
來清零內存塊。對於 C/C++ 來說使用 memset
其實也是一樣的,具體用什麼看應用場合了,編寫跨平臺的應用程序應該使用標準庫。
依賴信息:
名稱 | 值 |
---|---|
Header | WinBase.h (include Windows.h) |
某些編譯器在開啓優化的情況下,可能會忽略掉對 memset
或者是 ZeroMemory
的調用,此時應該使用另一個ZeroMemory
的安全版本 SecureZeroMemory
:
PVOID SecureZeroMemory(
_In_ PVOID ptr,
_In_ SIZE_T cnt
);
參數和 ZeroMemory
都是完全一樣的,區別在於 SecureZeroMemory
返回一個指向內存塊的指針,下面是一個使用 SecureZeroMemory
代替 ZeroMemory
的例子,取自MSDN。
WCHAR szPassword[MAX_PATH];
// Retrieve the password
if (GetPasswordFromUser(szPassword, MAX_PATH))
UsePassword(szPassword);
// Clear the password from memory
SecureZeroMemory(szPassword, sizeof(szPassword));
在內存清0以後,該程序後面沒有再引用 szPassword
,因此如果使用 ZeroMemory
就有可能會被編譯器優化掉,但是該變量的原始值仍然保留在棧上,仍然可以通過其他途徑被訪問到,而這一塊內存的內容是密碼,出於安全考慮,我們無論如何都應該講這段內存清0。