gpt4 book ai didi

c++ - Visual Leak Detector 报告一个 int* 有 40 个字节泄漏

转载 作者:可可西里 更新时间:2023-11-01 18:36:46 32 4
gpt4 key购买 nike

这是我的程序

#include <vld.h>

using namespace std;

int main() {
int* p = new int(100);
}

视觉检漏报告

Visual Leak Detector Version 2.3 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x00891B60: 4 bytes ----------
Call Stack:
c:\xxx\documents\visual studio 2010\projects\stl1\stl1\stl1.cpp (11): stl1.exe!main + 0x7 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): stl1.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): stl1.exe!mainCRTStartup
0x76B7338A (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
0x774B97F2 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes
0x774B97C5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes
Data:
64 00 00 00 d....... ........


Visual Leak Detector detected 1 memory leak (40 bytes).
Largest number used: 40 bytes.
Total allocations: 40 bytes.
Visual Leak Detector is now exiting.
The program '[8992] stl1.exe: Native' has exited with code 0 (0x0).

为什么 40 字节 内存泄漏,它确实应该是 4 字节

谁能解释一下这是怎么回事?

最佳答案

首先,当您要求分配 4 个字节时,您总是会得到一个更大的 block 的可能性很高(这是安全的,因为您应该只使用您要求的 4 个字节)。

为什么?

  1. 分配大小必须存储在某处(考虑 new X[count] 情况,而 delete[] 必须调用 count 次 X 的析构函数

  2. 然后,堆分配通常通过堆的递归碎片来完成,例如 the Buddy_memory_allocation .这是因为您希望开销尽可能低(即,用于管理分配的字节数与实际分配的字节数相比)。您需要记住是否使用了某个内存块。

  3. 调试也可能会增加分配大小。在 Visual Studio 上,malloc/free 函数在返回的指针之前插入 4 个字节,带有“内存保护”,如 ( 0xDDDDDDDD ),并在请求的大小之后为另一个内存保护再分配 4 个字节。当您调用 malloc 或 free(间接调用 new 和 delete)时,堆处理程序的代码会检查守卫并断言它们未被修改。如果是,它会停止你的程序,这样你就可以看到内存被修改的地方“周围”。 IIRC, 0xCDCDCDCD用于填充分配区域,0xFEEEFEEE用于填充释放区域但 block 尚未返回到系统,并且0xDDDDDDDD用于边界。

因此即使您只使用“4”,您收到的 block 的大小似乎也是 40 个字节(可能更多)。VLD 不会跟踪您的代码,它会拦截内存管理函数(如 malloc/free ),并构建每个已分配 block 的列表。解析此列表以在释放元素时将其删除。终止后,将列出任何剩余项目。

因此收到的 malloc 调用可能来自 ::operator new将请求的大小扩大到 40 字节,或者可能在 VLD 中添加了一个 32 字节的 block 来跟踪“分配请求”。

看了VLD source code之后,特别是 vldnew 函数,它为每个分配分配一个 header :

vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(g_vldHeap, 0x0, size + sizeof(vldblockheader_t))

很可能,vldblockheader_t在你的情况下是 36 个字节。

关于c++ - Visual Leak Detector 报告一个 int* 有 40 个字节泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32885513/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com