简体   繁体   English

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

[英]FastMM reports memory leaks on STL containers in C++ Builder 6

When I create an empty console application and use an STL container in it, FastMM reports a memory leak when the application is closed. 当我创建一个空的控制台应用程序并在其中使用STL容器时,当应用程序关闭时,FastMM报告内存泄漏。

For example, if I create a std::vector<int> in main() : 例如,如果我在main()创建一个std::vector<int>

std::vector<int> v;

Compile, run and close, no leaks are reported. 编译,运行和关闭,没有泄漏报告。

If I do: 如果我做:

std::vector<int> v;
v.push_back(100);

I get: 我得到:

This application has leaked memory. 该应用程序泄漏了内存。 The small block leaks are: 小块泄漏为:

309 - 340 bytes: Unknown x 1 309-340字节:未知x 1

Similarly, I get a leak reported on: 同样,我收到有关以下内容的泄漏的报告:

std::vector<int> v;
v.push_back(100);
v.clear();

And also a leak is reported on: 并且还报告了泄漏:

std::vector<int> v;
v.reserve(1);

For some containers, like std::deque , its enough just to create one, and even without altering its content a leak is reported when the application is closed. 对于某些容器,例如std::deque ,它足以创建一个容器,即使不更改其内容,在关闭应用程序时也会报告泄漏。

Can anyone explain what is happening? 谁能解释发生了什么事? I use Borland C++Builder 6 and FastMM4. 我使用Borland C ++ Builder 6和FastMM4。 I've been changing various settings in FastMMOptions.inc , however I'm still seeing these leaks reported. 我一直在更改FastMMOptions.inc各种设置,但是仍然看到这些泄漏的报告。

Clearing a std::vector does not deallocate the memory used for the vector 's internal array, it merely destructs the items inside the array and then sets the std::vector::size() to 0. The array itself is still allocated so it can be reused for new items pushed in the vector . 清除std::vector不会释放用于vector的内部数组的内存,它只是破坏数组内部的项,然后将std::vector::size()为0。仍然分配数组本身因此它可以用于vector推送的新项目。 The vector 's destructor will deallocate the array. vector的析构函数将取消分配数组。

In C++Builder 6, the default STL library is STLPort (replaced with Dinkumware in C++Builder 2006). 在C ++ Builder 6中,默认的STL库是STLPort(在C ++ Builder 2006中用Dinkumware代替)。 STLPort's implementation of the ~std::vector() merely destructs the array items (as if clear() has been called) but does not deallocate the array itself, thus the "leak" you are seeing. STLPort对~std::vector()仅破坏了数组项(就好像调用了clear() ),而没有取消分配数组本身,因此,您将看到“泄漏”。 Which is not actually a leak at all, according to the following FAQ on the STLPort website: 根据STLPort网站上的以下常见问题解答,这实际上根本不是泄漏:

Q6.2 My tool detect memory leaks in application with STLport. Q6.2我的工具使用STLport检测应用程序中的内存泄漏。 Is this leak from STLport? 是STLport泄漏吗?

A6.2 In most cases this are 'pseudo memory leaks' that some tools wrongly supports. A6.2在大多数情况下,这是某些工具错误支持的“伪内存泄漏”。

In the default compile of STLport, the node allocator is used to allocate internal memory. 在STLport的默认编译中,节点分配器用于分配内部内存。 The node allocator works by pre-allocating a large chunk of memory and handing out small memory blocks out. 节点分配器通过预分配大块内存并分发小块内存来工作。 The memory chunk is not freed during running an application that uses STLport (ie it don't returned to system, There are tools like BoundsChecker, Purify or Valgrind that check for memorytml leaks, for memory that isn't freed when no longer used. These tools may report false memory leaks when one uses STLport's node allocator. The memory chunk is normally freed at application end, but the memory checkers usually report memory leaks before that point . Another memory problem might be reported when you use shared libraries (eg DLL, this problem specific for Windows DLL model) that uses STLport internally and are statically link to it. If memory is allocated in a dll and released in an other then the STLport node allocator will keep the released memory for a future use. If you do not use this memory then your application global memory consumtion will grow until the appli crash even if there is no realy memory leak. This is why you should always use a coherent configuration everything in d 在运行使用STLport的应用程序期间,不会释放内存块 (即,它不返回系统。有一些工具,例如BoundsChecker,Purify或Valgrind,用于检查memorytml泄漏,用于不再使用时不再释放的内存。 这些工具可能会在使用STLport的节点分配器时报告错误的内存泄漏。通常在应用程序端释放内存块,但是内存检查程序通常会在此之前报告内存泄漏 。当您使用共享库(例如DLL)时,可能会报告另一个内存问题。 ,此问题特定于Windows DLL模型),该问题在内部使用STLport并静态链接到它。如果在dll中分配内存并在另一个内存中释放,则STLport节点分配器将保留释放的内存以供将来使用。如果不使用此内存,那么即使没有真正的内存泄漏,应用程序的全局内存消耗也会增加,直到应用程序崩溃为止,这就是为什么您应该始终对所有d使用一致的配置的原因 ll or everything in static lib. ll或静态lib中的所有内容。

There are ways to remove the pseudo memory leaks (since the memory is properly freed at the end of the program, the leaks are just pseudo-ones). 有多种方法可以消除伪内存泄漏(由于在程序结束时已正确释放了内存,因此泄漏只是伪1)。 You could use another allocator that is used in STLport. 您可以使用STLport中使用的另一个分配器。 Open the file "stlport/stl/_site_config.h" and uncomment either one of the following: 打开文件"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" 

The new/delete allocator has the advantage of giving an entry point to track memory starvation, see set_new_handler in your compiler doc or the C++ Standard for more information. new / delete分配器的优点是为跟踪内存不足提供了一个入口点,有关更多信息,请参见编译器文档或C ++ Standard中的set_new_handler。

Alternatively you can define the following symbol, just uncomment it in "stlport/stl/_site_config.h" . 或者,您可以定义以下符号,只需在"stlport/stl/_site_config.h"取消注释"stlport/stl/_site_config.h"

 _STLP_LEAKS_PEDANTIC 

The symbol forces freeing all memory chunks. 该符号强制释放所有内存块。 Also see the comments around the symbol in the config file. 另请参阅配置文件中符号周围的注释。

Note that you have to recompile STLport AND your application and all of your dependent libraries if you make any change to the file! 请注意,如果对文件进行任何更改,则必须重新编译STLport和应用程序以及所有从属库!

There are also some defines that help in debugging memory problems in STLport. 还有一些定义可以帮助调试STLport中的内存问题。 In _STLP_DEBUG mode, just also define the following symbols, either in "./stlport/stl_user_config.h" or in your project settings: 在_STLP_DEBUG模式下,只需在“ ./stlport/stl_user_config.h”或项目设置中定义以下符号:

 _STLP_DEBUG_ALLOC _STLP_DEBUG_UNINITIALIZED 

You don't need to rebuild STLport for these options, but you have to rebuild your application and all of your dependent libraries if you make any change to the file. 您不需要为这些选项重建STLport,但是如果对文件进行任何更改,则必须重建应用程序和所有从属库。

That said, the RogueWave STL, which was used in earlier C++Builder versions, is also shipped with C++Builder 6 for backwards compatibility with older code, and does not suffer from this issue. 也就是说,在C ++ Builder早期版本中使用的RogueWave STL也随C ++ Builder 6一起提供,以向后兼容较早的代码,并且不会遇到此问题。 You can switch from STLPort to RogueWave by defining _USE_OLD_RW_STL in your project's conditionals list. 您可以通过在项目的条件列表中定义_USE_OLD_RW_STL_USE_OLD_RW_STL切换到RogueWave。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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