2016-07-25 59 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()后发生。

相关问题