7

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

我的问题是,追踪起来非常耗时。损坏后错误被抛出,我不得不手动调试整个运行以查找何时覆盖缓冲区结束。

是否有任何工具\方法可以帮助追踪此问题?如果程序会立即崩溃,我会更快地发现问题......

问题的一个例子:

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

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

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

4 回答 4

4

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

00397848 处的堆块在 0039789C 处修改,请求大小为 4c

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

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

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_DELAY_FREE_MEM_DF);
于 2012-06-10T18:14:55.473 回答
3

我使用pageheap。这是一个来自 Microsoft 的工具,它改变了分配器的工作方式。使用 pageheap 时,当您调用 malloc 时,分配会向上舍入到最近的页面(内存块),并在其后放置一个设置为 no-read/no-write 的附加虚拟内存页面。您分配的动态内存是对齐的,以便缓冲区的末尾正好在虚拟页面之前的页面末尾之前。这样,如果您越过缓冲区的边缘,通常是一个字节,调试器就可以轻松捕获它。

于 2012-06-11T04:59:31.200 回答
2

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

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

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

编辑:在您的代码片段上尝试夹板时,我收到以下警告:

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

大概这个警告会帮助你。

于 2012-06-10T12:18:33.457 回答
0

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

许多动态检查器仅捕获对象外部的访问,并且仅在对象是堆分配的情况下才捕获。CheckPointer 将堆分配的对象中发现内存访问错误;无论字段类型如何,访问结构中字段的末尾都是非法的;大多数动态检查器无法检测到此类错误。它还将找到本地人边缘的访问权限。

于 2012-06-26T08:08:49.153 回答