2016-07-25 35 views
1

在試驗保留和提交虛擬內存到一個進程中,我分配了64K字節的內存與VirtualAlloc,memcpy'da測試字符串到它,printf'它像一個字符串,釋放內存VirtualFreeMEM_RELEASE標誌和printf'd it again。出於某種原因,不會觸發頁面錯誤。爲什麼是這樣?空閒的內存不會導致頁面錯誤

#include <stdio.h> 
#include <windows.h> 

INT main(DWORD argc, LPSTR argv[]) { 
    SYSTEM_INFO info; 
    DWORD dwPageSize; 
    DWORD dwMemSize; 
    LPVOID lpvMem; 

    GetSystemInfo(&info); 
    dwPageSize = info.dwPageSize; 
    dwMemSize = 16 * dwPageSize; 

    lpvMem = VirtualAlloc((LPVOID) 0x00F00000, dwMemSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 
    if (!lpvMem) { 
     printf("Error allocating virtual memory\n"); 
     return 1; 
    } 

    printf("lpvMem = 0x%08X\n", (UINT32) (UINT64) lpvMem); 

    if (!memcpy(lpvMem, "I love foxes \\(^o^)/", 21)) { 
     printf("Error copying memory (error code 0x%08X)\n", GetLastError()); 
     return 1; 
    } 

    printf("Before free: %s\n", (LPCSTR) lpvMem); 
    VirtualFree(lpvMem, dwMemSize, MEM_RELEASE); 
    printf("After free: %s\n", (LPCSTR) lpvMem); 

    fflush(stdout); 

    return 0; 
} 

輸出:

lpvPagedMemory = 0x00F00000 
Before free: I love foxes \(^o^)/ 
After free: I love foxes \(^o^)/ 
+2

否在哪裏定義訪問釋放的內存會導致頁面錯誤。它*可能會導致頁面錯誤。但這並不確定。在C中,這稱爲未定義行爲。任何有UB的代碼都被認爲是bug(即使程序的某些運行沒有表現出明顯的「壞」行爲)。這個問題有更多的細節:[未定義,未指定和實現定義的行爲](http:// stackoverflow .com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) – kaylum

+2

VirtualFree(lpvMem,0,MEM_RELEASE); - 這是正確的代碼。 VirtualFree(lpvMem,dwMemSize,MEM_RELEASE); - error - 「如果dwFreeType參數是MEM_RELEASE,則此參數必須爲0」 – RbMm

+2

@kaylum它是Windows **上定義的確定性**。 C沒有定義它,但Windows確實如此。 – immibis

回答

10

這條線:

VirtualFree(lpvMem, dwMemSize, MEM_RELEASE); 

是錯誤的。你是不是檢查什麼VirtualFree()回報,以及文檔說:

的dwSize [中]
...
如果dwFreeType參數MEM_RELEASE,這個參數必須爲0 (零)。該函數將初始分配調用中保留的整個區域釋放到VirtualAlloc中。

所以你需要使用它代替:

VirtualFree(lpvMem, 0, MEM_RELEASE); 

關於頁面錯誤 - 它可以(而且必須)只有成功調用VirtualFree()後發生。

相關問題