C 释放的内存不会导致页面错误

C 释放的内存不会导致页面错误,c,windows,winapi,virtual-memory,C,Windows,Winapi,Virtual Memory,在尝试保留虚拟内存并将其提交给进程时,我使用VirtualAlloc分配了64K字节的内存,memcpy将一个测试字符串放入其中,printf“它就像一个字符串一样,使用VirtualFree和MEM\u RELEASE标志释放内存,然后再打印一次。由于某些原因,不会触发页面错误。为什么会这样 #include <stdio.h> #include <windows.h> INT main(DWORD argc, LPSTR argv[]) { SYSTEM_I

在尝试保留虚拟内存并将其提交给进程时,我使用
VirtualAlloc
分配了64K字节的内存,
memcpy
将一个测试字符串放入其中,
printf
“它就像一个字符串一样,使用
VirtualFree
MEM\u RELEASE
标志释放内存,然后再打印一次。由于某些原因,不会触发页面错误。为什么会这样

#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;
}
这一行:

VirtualFree(lpvMem, dwMemSize, MEM_RELEASE);
这是一个错误。您没有检查返回的内容,文档显示:

dwSize[in]

如果dwFreeType参数为MEM_RELEASE,此参数必须为0 (零)。该函数释放在对VirtualAlloc的初始分配调用中保留的整个区域

因此,您需要使用此选项:

VirtualFree(lpvMem, 0, MEM_RELEASE);
关于页面错误-它只能(而且必须)在成功调用
VirtualFree()

这一行之后发生:

VirtualFree(lpvMem, dwMemSize, MEM_RELEASE);
这是一个错误。您没有检查返回的内容,文档显示:

dwSize[in]

如果dwFreeType参数为MEM_RELEASE,此参数必须为0 (零)。该函数释放在对VirtualAlloc的初始分配调用中保留的整个区域

因此,您需要使用此选项:

VirtualFree(lpvMem, 0, MEM_RELEASE);

关于页面错误-只有在成功调用
VirtualFree()

之后才会发生(而且必须发生)

没有定义访问释放内存会导致页面错误。它可能会导致页面错误。但这不是必然的。在C语言中,这称为未定义的行为。任何有UB的代码都被认为是有缺陷的(即使程序的某些运行没有表现出明显的“坏”行为)。这个问题有更多的细节:VirtualFree(lpvMem,0,MEM_发行版);-这是正确的代码。VirtualFree(lpvMem、dwMemSize、MEM_发行版);-错误-“如果dwFreeType参数是MEM_RELEASE,则此参数必须为0”@kaylum这是Windows上定义的确定性参数。C没有定义它,但Windows有。@user3386109-这里没有“局部变量的内存是否可以在其作用域之外访问”的共同点。这里是VirtualFree api调用的错误,第二个参数错误-必须为0才能重新打开,因为这不是重复的。没有定义访问释放内存将导致页面错误的位置。它可能会导致页面错误。但这不是必然的。在C语言中,这称为未定义的行为。任何有UB的代码都被认为是有缺陷的(即使程序的某些运行没有表现出明显的“坏”行为)。这个问题有更多的细节:VirtualFree(lpvMem,0,MEM_发行版);-这是正确的代码。VirtualFree(lpvMem、dwMemSize、MEM_发行版);-错误-“如果dwFreeType参数是MEM_RELEASE,则此参数必须为0”@kaylum这是Windows上定义的确定性参数。C没有定义它,但Windows有。@user3386109-这里没有“局部变量的内存是否可以在其作用域之外访问”的共同点。这里是VirtualFree api调用的错误,第二个参数错误-必须为0才能重新打开,因为这不是重复的。