2016-07-25 20 views
1

Beim Experimentieren mit dem Reservieren und Übertragen von virtuellem Speicher an einen Prozess habe ich 64K Bytes Speicher mit VirtualAlloc, memcpy 'da test string zugewiesen, printf' d es mag eine Zeichenfolge, befreit den Speicher mit VirtualFree mit dem MEM_RELEASE Flag und printf 'd es wieder. Aus irgendeinem Grund wird kein Seitenfehler ausgelöst. Warum ist das?Freigegebener Speicher, der keinen Seitenfehler verursacht

#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; 
} 

Ausgang:

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

Nein, wo ist definiert, dass der Zugriff auf freigegebenen Speicher einen Seitenfehler verursacht. Es * kann * einen Seitenfehler verursachen. Aber das ist keine Gewissheit. In C heißt das Undefined Behavior. Jeder Code, der UB hat, wird als fehlerhaft angesehen (selbst wenn einige Runs des Programms kein offensichtliches "schlechtes" Verhalten aufweisen). Diese Frage enthält weitere Details: [Undefiniertes, nicht spezifiziertes und implementierungsdefiniertes Verhalten] (http: // stackoverflow .com/questions/2397984/undefined-unspecified-und-implementation-defined-behavior) – kaylum

+2

VirtualFree (lpvMem, 0, MEM_RELEASE); - Das ist der richtige Code. VirtualFree (lpvMem, dwMemSize, MEM_RELEASE); - error - "Wenn der Parameter dwFreeType MEM_RELEASE ist, muss dieser Parameter 0 sein" – RbMm

+2

@kaylum Es ist eine definierte Sicherheit ** unter Windows **. C definiert es nicht, aber Windows tut es. – immibis

Antwort

10

Diese Zeile:

VirtualFree(lpvMem, dwMemSize, MEM_RELEASE); 

ist ein Fehler. Du bist gerade nicht, was VirtualFree() zurückkehrt, und die Dokumentation sagt:

dwSize [in]
...
Wenn der dwFreeType Parameter MEM_RELEASE ist, dieser Parameter 0 (Null) sein muss. Die Funktion gibt die gesamte Region frei, die in dem ersten Zuordnungsaufruf an VirtualAlloc reserviert ist.

So müssen Sie diese stattdessen verwenden:

VirtualFree(lpvMem, 0, MEM_RELEASE); 

über den Seitenfehler - es kann (und muß) erst nach einem erfolgreichen Aufruf VirtualFree() passieren.