[英]FastMM reports memory leaks on STL containers in C++ Builder 6
当我创建一个空的控制台应用程序并在其中使用STL容器时,当应用程序关闭时,FastMM报告内存泄漏。
例如,如果我在main()
创建一个std::vector<int>
:
std::vector<int> v;
编译,运行和关闭,没有泄漏报告。
如果我做:
std::vector<int> v;
v.push_back(100);
我得到:
该应用程序泄漏了内存。 小块泄漏为:
309-340字节:未知x 1
同样,我收到有关以下内容的泄漏的报告:
std::vector<int> v;
v.push_back(100);
v.clear();
并且还报告了泄漏:
std::vector<int> v;
v.reserve(1);
对于某些容器,例如std::deque
,它足以创建一个容器,即使不更改其内容,在关闭应用程序时也会报告泄漏。
谁能解释发生了什么事? 我使用Borland C ++ Builder 6和FastMM4。 我一直在更改FastMMOptions.inc
各种设置,但是仍然看到这些泄漏的报告。
清除std::vector
不会释放用于vector
的内部数组的内存,它只是破坏数组内部的项,然后将std::vector::size()
为0。仍然分配数组本身因此它可以用于vector
推送的新项目。 vector
的析构函数将取消分配数组。
在C ++ Builder 6中,默认的STL库是STLPort(在C ++ Builder 2006中用Dinkumware代替)。 STLPort对~std::vector()
仅破坏了数组项(就好像调用了clear()
),而没有取消分配数组本身,因此,您将看到“泄漏”。 根据STLPort网站上的以下常见问题解答,这实际上根本不是泄漏:
Q6.2我的工具使用STLport检测应用程序中的内存泄漏。 是STLport泄漏吗?
A6.2在大多数情况下,这是某些工具错误支持的“伪内存泄漏”。
在STLport的默认编译中,节点分配器用于分配内部内存。 节点分配器通过预分配大块内存并分发小块内存来工作。 在运行使用STLport的应用程序期间,不会释放内存块 (即,它不返回系统。有一些工具,例如BoundsChecker,Purify或Valgrind,用于检查memorytml泄漏,用于不再使用时不再释放的内存。 这些工具可能会在使用STLport的节点分配器时报告错误的内存泄漏。通常在应用程序端释放内存块,但是内存检查程序通常会在此之前报告内存泄漏 。当您使用共享库(例如DLL)时,可能会报告另一个内存问题。 ,此问题特定于Windows DLL模型),该问题在内部使用STLport并静态链接到它。如果在dll中分配内存并在另一个内存中释放,则STLport节点分配器将保留释放的内存以供将来使用。如果不使用此内存,那么即使没有真正的内存泄漏,应用程序的全局内存消耗也会增加,直到应用程序崩溃为止,这就是为什么您应该始终对所有d使用一致的配置的原因 ll或静态lib中的所有内容。
有多种方法可以消除伪内存泄漏(由于在程序结束时已正确释放了内存,因此泄漏只是伪1)。 您可以使用STLport中使用的另一个分配器。 打开文件
"stlport/stl/_site_config.h"
然后取消注释以下任意一项:_STLP_USE_NEWALLOC enables a simple allocator that uses "new/delete" _STLP_USE_MALLOC enables a simple allocator that uses "malloc/free"
new / delete分配器的优点是为跟踪内存不足提供了一个入口点,有关更多信息,请参见编译器文档或C ++ Standard中的set_new_handler。
或者,您可以定义以下符号,只需在
"stlport/stl/_site_config.h"
取消注释"stlport/stl/_site_config.h"
。_STLP_LEAKS_PEDANTIC
该符号强制释放所有内存块。 另请参阅配置文件中符号周围的注释。
请注意,如果对文件进行任何更改,则必须重新编译STLport和应用程序以及所有从属库!
还有一些定义可以帮助调试STLport中的内存问题。 在_STLP_DEBUG模式下,只需在“ ./stlport/stl_user_config.h”或项目设置中定义以下符号:
_STLP_DEBUG_ALLOC _STLP_DEBUG_UNINITIALIZED
您不需要为这些选项重建STLport,但是如果对文件进行任何更改,则必须重建应用程序和所有从属库。
也就是说,在C ++ Builder早期版本中使用的RogueWave STL也随C ++ Builder 6一起提供,以向后兼容较早的代码,并且不会遇到此问题。 您可以通过在项目的条件列表中定义_USE_OLD_RW_STL
从_USE_OLD_RW_STL
切换到RogueWave。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.