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

标签 c++ stl c++builder c++builder-6 fastmm

当我创建一个空的控制台应用程序并在其中使用 STL 容器时,FastMM 在应用程序关闭时报告内存泄漏。

例如,如果我创建一个 std::vector<int>main() :

std::vector<int> v;

编译、运行并关闭,没有报告泄漏。

如果我这样做:

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

我得到:

This application has leaked memory. The small block leaks are:

309 - 340 bytes: Unknown 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 My tool detect memory leaks in application with STLport. Is this leak from STLport?

A6.2 In most cases this are 'pseudo memory leaks' that some tools wrongly supports.

In the default compile of STLport, the node allocator is used to allocate internal memory. 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 (i.e. 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 (e.g. 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 dll or everything in static 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). You could use another allocator that is used in STLport. Open the file "stlport/stl/_site_config.h" and uncomment either one of the following:

_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.

Alternatively you can define the following symbol, just uncomment it in "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!

There are also some defines that help in debugging memory problems in 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_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.

也就是说,在较早的 C++Builder 版本中使用的 RogueWave STL 也随 C++Builder 6 一起提供,以便与旧代码向后兼容,并且不会遇到此问题。您可以通过在项目的条件列表中定义 _USE_OLD_RW_STL 从 STLPort 切换到 RogueWave。

关于c++ - FastMM 报告 C++ Builder 6 中的 STL 容器内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38202042/

相关文章:

c++ - 如何通过 Chrome Pepper C API 创建和打开文件系统?

c++ - 我应该如何存储对象

C++ 排序的对象集

c++ - 在 C++ Builder 中更新 TDBGrid

delphi - 从隐藏的 TWebBrowser 关闭时访问冲突

c++ - 静态 char* 的数组

c++ - 堆栈和 vtable [重新] 位置

c++ - 使用 STL 容器查找序列的 k 个最大元素的最快算法是什么

STL - c++0x 中的不可变设置键在哪里?

c++ - 在一行中调用 TDataSet.Locate