2016-07-25 10 views
1

仮想メモリをプロセスに予約して試してみると、私はVirtualAllocmemcpy 'daテスト文字列にの文字列のようにメモリを解放して64Kバイトのメモリを割り当てましたMEM_RELEASEフラグのあるVirtualFreeと、printfというフラグが再度表示されます。何らかの理由で、ページフォールトがトリガされません。どうしてこれなの?解放されたメモリがページフォールトを引き起こさない

#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を持つコードはバグがあると見なされます(プログラムの実行によって明白な「悪い」動作が発生しなくても)。この質問には詳細があります:[未定義、未定義、実装定義の動作](http:// stackoverflow .com/questions/2397984 /未定義 - 未指定および実装定義の動作) – kaylum

+2

VirtualFree(lpvMem、0、MEM_RELEASE);これは正しいコードです。 VirtualFree(lpvMem、dwMemSize、MEM_RELEASE); - エラー - "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()から成功コールの後に発生する可能性があります。

関連する問題