5

我只是在 Borland C++ Builder 版本 6 中运行以下代码;

for (int i = 0; i < 40000; i++)
{      
   try {
     __int64 n = 0;
     __int64 r = 1 / n;
   }
   catch (Exception& e) {}
}

在运行此循环时,我在任务管理器(内存列)中看到它正在泄漏内存。知道为什么吗?

当我尝试除以零时,我在项目中的计算模块上工作时遇到内存泄漏,并且在我的头撞了好几个小时后,内存泄漏在哪里,我意识到它也在上述简单循环中泄漏内存。项目中没有发现问题。

4

2 回答 2

4

从标准 5/4 我们了解到:

如果在计算表达式期间,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义。

因此,由于除以零在数学上没有定义,因此行为是未定义的。未定义的行为包括内存泄漏,因此进一步推测它为什么会泄漏内存是不值得的(尽管像 valgrind 这样的工具可能能够帮助您识别来源)。

于 2013-09-18T14:13:35.077 回答
2

任务管理器不是用于测试内存泄漏的好工具。它只能报告进程分配了多少内存,而不能报告该进程如何使用内存。

您没有考虑到的是 C++Builder 的内存管理器缓存释放的内存,它不会立即将其返回给操作系统。您可能看到的是内存碎片,而不是内存泄漏。碎片可以防止内存管理器重用它已经缓存的内存,使其分配越来越多的操作系统内存。这将导致您在任务管理器中看到的行为。如果您查看任务管理器的Page Faults专栏,您会看到该值随着内存使用量的增加而上升。这很好地表明内存没有被重用。

话虽如此,C++Builder 6 使用的默认内存管理器并不是最好的内存管理器。它在以后的版本中被FastMM取代,它也可以在 C++Builder 6 中使用。FastMM 不会受到内存碎片的影响。

于 2013-09-18T20:47:46.137 回答