繁体   English   中英

FastMM报告C ++ Builder 6中STL容器上的内存泄漏

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM