C++ HeapWalk在释放模式下未按预期工作

C++ HeapWalk在释放模式下未按预期工作,c++,memory,memory-management,heap,C++,Memory,Memory Management,Heap,所以我用HeapWalk函数的例子将它实现到我的应用程序中。我玩了一下,当我添加时,我看到了这一点 HANDLE d = HeapAlloc(hHeap, 0, sizeof(int)); int* f = new(d) int; 创建堆后,将记录一些新的输出: Allocated block Data portion begins at: 0X037307E0 Size: 4 bytes Overhead: 28 bytes Region index: 0 看到这一点,我想我

所以我用HeapWalk函数的例子将它实现到我的应用程序中。我玩了一下,当我添加时,我看到了这一点

HANDLE d = HeapAlloc(hHeap, 0, sizeof(int));
int* f = new(d) int;
创建堆后,将记录一些新的输出:

Allocated block  Data portion begins at: 0X037307E0
  Size: 4 bytes
  Overhead: 28 bytes
  Region index: 0
看到这一点,我想我可以检查
Entry.wFlags
,看看它是否被设置为
PROCESS\u HEAP\u Entry\u BUSY
,以跟踪我在堆上使用了多少分配的内存。因此,我:

HeapLock(heap);

int totalUsedSpace = 0, totalSize = 0, largestFreeSpace = 0, largestCounter = 0;

PROCESS_HEAP_ENTRY entry;
entry.lpData = NULL;
while (HeapWalk(heap, &entry) != FALSE)
{
    int entrySize = entry.cbData + entry.cbOverhead;

    if ((entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0)
    {
        // We have allocated memory in this block
        totalUsedSpace += entrySize;
        largestCounter = 0;
    }
    else
    {
        // We do not have allocated memory in this block
        largestCounter += entrySize;
        if (largestCounter > largestFreeSpace)
        {
            // Save this value as we've found a bigger space
            largestFreeSpace = largestCounter;
        }
    }

    // Keep a track of the total size of this heap
    totalSize += entrySize;
}

HeapUnlock(heap);
在调试模式下构建时,这似乎可以工作(
totalSize
totalUsedSpace
是不同的值)。但是,当我在发布模式下运行它时,
totalUsedSpace
始终为0

在发布模式下,我使用调试器逐步完成了它,对于每个堆,它会循环三次,并在
条目中获得以下标志。通过调用
HeapWalk
,wFlags

1 (PROCESS_HEAP_REGION)
0
2 (PROCESS_HEAP_UNCOMMITTED_RANGE)
然后退出
,而
循环,GetLastError()按预期返回
ERROR\u NO\u MORE\u项

从中,我发现
0
的标志值是“提交的块是自由的,即未分配或未用作控制结构。”

有人知道为什么它在发布模式下无法正常工作吗?我对计算机如何处理内存没有太多经验,所以我不确定错误可能来自哪里。在谷歌上搜索没有得到任何结果,所以希望这里有人知道


更新:我自己仍在研究这个问题,如果我使用vmmap监控应用程序,我可以看到进程有9个堆,但调用
GetProcessHeaps
时返回有22个堆。此外,它返回的堆句柄中没有一个与
GetProcessHeap()
\u get\u heap\u handle()
的返回值匹配。似乎
GetProcessHeaps
的行为不符合预期。以下是获取堆列表的代码:

// Count how many heaps there are and allocate enough space for them
DWORD numHeaps = GetProcessHeaps(0, NULL);
HANDLE* handles = new HANDLE[numHeaps];

// Get a handle to known heaps for us to compare against
HANDLE defaultHeap = GetProcessHeap();
HANDLE crtHeap = (HANDLE)_get_heap_handle();

// Get a list of handles to all the heaps
DWORD retVal = GetProcessHeaps(numHeaps, handles);

retVal
的值与
numHeaps
的值相同,表示没有错误

应用程序验证程序之前已设置为对我的可执行文件执行整页堆验证,并且正在干扰由
GetProcessHeaps
返回的堆。我忘记了它是在几天前为另一个问题设置的,然后在没有清除测试的情况下关闭。这在调试生成中没有发生,因为应用程序为调试生成生成生成不同的文件名


我们通过添加一个断点并查看线程的调用堆栈来检测这一点。我们可以看到AV DLL已经被注入,这让我们知道应该在哪里查找。

您在HeapWalk前后使用HeapLock和HeapUnlock吗?是的,为了简洁起见,我省略了实际的
HeapWalk
函数的代码。我将把它们添加到代码段中您是使用调试器检查变量(包括
totalUsedSpace
),还是将它们写入调试器控制台/stdout/file?因为在检查发布版本时,调试器可能会对变量内容撒谎。这些值正在写入文本文件。我自己仍在研究这个问题,如果我使用vmmap监视应用程序,我可以看到该进程有9个堆,但调用
GetProcessHeaps
时,它返回有22个堆。此外,它返回的堆句柄中没有一个与
GetProcessHeap()
\u get\u heap\u handle()
的返回值匹配。似乎
GetProcessHeaps
的行为不符合预期。