【问题标题】:Properly release allocated virtual memory正确释放分配的虚拟内存
【发布时间】:2015-12-17 08:20:45
【问题描述】:

我一直想知道 CPU 需要多少时间来处理大量 NOP 操作并以某种方式计算每秒的总操作数,所以我想出了以下代码:

#include <string.h>
#include <stdio.h>
#include <time.h>
#include <Windows.h>

int main(){
    printf("NOP watch\n");
    LPCH buffer=0;
    int count=0;
    while (true){
        int success=0;
        do {
            printf("NOP count: ");
            int success=scanf("%d", &count);
        } while (success);
        buffer = (LPCH)VirtualAlloc(0, count + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (!buffer){
            printf("Not enough RAM available, code: %d!\n",GetLastError());
        }
        else {
            for (int i = 0; i < count; i++)
                buffer[i] = '\x90';
            buffer[count] = 0xC3;
            clock_t start = clock();
            ((void(*)())buffer)();
            float t = (clock() - start) / (CLOCKS_PER_SEC * 1.0f);
            printf(" Time: %f, operations per second: %.3f M\n", t, (count / t) / 1e6);
            VirtualFree(buffer, count + 1, MEM_RELEASE);
            MEMORYSTATUSEX statex;
            statex.dwLength = sizeof(statex);
            GlobalMemoryStatusEx(&statex);
            printf("  Available virtual memory: %.2f/%.2f MB\n", statex.ullAvailVirtual / (1024.0f*1024.0f), statex.ullTotalVirtual / (1024.0f * 1024.0f));
        }
    }
}

我只是分配count + 1 字节的内存,在那里写入count NOP 和RET,调用内存块,然后释放内存。 但不知何故,VirtualFree(buffer, count + 1, MEM_RELEASE) 并没有释放任何东西,而且我很快就耗尽了内存。哪里错了?

这是示例输出:

NOP count: 500000000
 Time: 0.086000, operations per second: 5813.954 M
  Available virtual memory: 1558.46/2047.88 MB
NOP count: 500000000
 Time: 0.094000, operations per second: 5319.149 M
  Available virtual memory: 1081.62/2047.88 MB
NOP count: 500000000
 Time: 0.105000, operations per second: 4761.905 M
  Available virtual memory: 604.78/2047.88 MB
NOP count: 500000000
Not enough RAM available, code: 8!

【问题讨论】:

  • 指向对象的指针转换为指向函数的指针未定义的行为
  • 当我明确定义它是充满NOP指令的可执行内存时,它是如何未定义的?在低级别,它很简单:CALL $Buffer.
  • 它不是未定义的,而是未定义的行为port70.net/~nsz/c/c11/n1570.html#6.3.2.3
  • 然后选择一种语言。这看起来像 C,但你也添加了 C++ 标签,所以请删除错误的标签。
  • 不,不是!不要传播这种废话!一些具有相同语法的结构具有不同的语义。如果你对这两种语言都足够了解,你就不会写这个。

标签: c winapi memory memory-management


【解决方案1】:

我不确定细节,但文档https://msdn.microsoft.com/en-us/library/windows/desktop/aa366892%28v=vs.85%29.aspx 指出,如果第三个参数是MEM_RELEASEVirtualFree 的第二个参数应该为零。

【讨论】:

  • 哇,WinAPI 调用是如此合乎逻辑。 -_-
  • @jakubinf:Windows API 比不阅读文档更符合逻辑。当您指向某人/某物时,您的 3 个手指指向您自己。
猜你喜欢
  • 2021-04-21
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 2016-03-15
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
相关资源
最近更新 更多