调试内存损坏

时间:2012-06-10 11:12:19

标签: c visual-studio-2010 visual-c++ memory-management memory-leaks

之前我在C(visual studio)中遇到了动态内存的问题。 我有一个或多或少的工作程序,在释放其中一个缓冲区时会产生运行时错误。这是一个明显的内存损坏,程序写在缓冲区的末尾。

我的问题是,追踪是非常耗时的。腐败后错误被抛弃了,我不得不手动调试整个运行以找到缓冲区末尾被覆盖的时间。

是否有任何工具\方式可以帮助您追踪此问题?如果程序会立即崩溃,我会发现问题的速度要快得多......

问题的一个例子:

int *pNum = malloc(10 * sizeof(int));

//                 ||
//                 \/    
for(int i = 0; i < 13; i++)
{
pNum[i] = 3;
}

// error....
free(pNum);

4 个答案:

答案 0 :(得分:3)

我使用“数据断点”。在你的情况下,当程序崩溃时,它可能会首先抱怨:

  <00>堆积块00397848在0039789C处修改,超过了要求的4c大小

然后,再次启动程序,并在地址0039789C设置数据断点。当代码写入该地址时,执行将停止。经常发生的是我此时立即发现了这个错误。

如果您的程序重复分配和释放内存,并且恰好位于此确切地址,则只需禁用deallocations:

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_DELAY_FREE_MEM_DF);

答案 1 :(得分:3)

我使用pageheap。这是Microsoft的一个工具,可以更改分配器的工作方式。打开pageheap时,当您调用malloc时,分配将向上舍入到最近的页面(内存块),并在其后面放置另一个设置为no-read / no-write的虚拟内存页面。您分配的动态内存已对齐,以便缓冲区的末尾位于虚拟页面之前的页面末尾之前。这样,如果你经常用一个字节遍历缓冲区的边缘,调试器就可以轻松捕获它。

答案 2 :(得分:2)

  

是否有任何工具\方式可以帮助您追踪此问题?

是的,这正是静态代码分析器试图找到的错误类型。例如splint / PC-Lint

以下是此类工具的列表: http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

编辑:在您的代码段中尝试拼接时,我收到以下警告:

  

main.c:9:2:可能的越界存储:pnum [i]

大概这个警告会帮助你。

答案 3 :(得分:0)

我们的CheckPointer工具可以帮助您查找内存管理错误。它适用于GCC 3/4和Microsoft方言C。

许多动态检查器只捕获对象外部的访问权限,然后才会捕获对象的堆分配。 CheckPointer将在堆内分配的对象中找到内存访问错误 ;无论字段类型如何,访问结构中字段的末尾都是非法的;大多数动态检查器无法检测到此类错误。它还可以找到当地人边缘的访问。