C ++的std :: string池,调试构建? std :: string和valgrind问题

时间:2010-06-08 10:27:02

标签: c++ string gcc memory-leaks valgrind

我有很多关于std :: string中可能存在内存泄漏的valgrind警告的问题,如下所示:

120 bytes in 4 blocks are possibly lost in loss record 4,192 of 4,687
    at 0x4A06819: operator new(unsigned long) (vg_replace_malloc.c:230)
    by 0x383B89B8B0: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)
    by 0x383B89C3B4: (within /usr/lib64/libstdc++.so.6.0.8)
    by 0x383B89C4A9: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)

我想知道:

  • std :: string(GCC 4.1.2)是否使用任何内存池?
  • 如果是这样,有没有办法禁用池(以调试构建等形式)?

6 个答案:

答案 0 :(得分:6)

检查FAQ。容器中有“内存泄漏”的部分。你应该

  • 检查您的Valgrind版本
  • 使用程序的调试版本(并且未经优化)
  • 并在必要时定义GLIBCXX_FORCE_NEW。 (这是一个影响程序运行时行为的环境变量,而不是您所期望的编译时#define。)

答案 1 :(得分:3)

这似乎是一种误报。这可以按照manual

中的描述进行抑制

答案 2 :(得分:2)

如果我没记错的话,很多STL分配器都会实现某种内存保留。 IE他们不会立即释放分配的内存,但要保留它并重复使用它。我肯定在valgrind中有很多误报来自我的STL实现分配的内存。

我发现处理问题的最好方法是(简单地)使用抑制文件。

答案 3 :(得分:1)

对于池来说,120字节是不够的。 Do you exit() from your program?

答案 4 :(得分:0)

我刚遇到这个问题,对我来说,这是因为我正在连接一个库的开发版本,但是我的测试代码正在拿起旧的系统安装版本。这些变化非常微妙,它可以连接并运行而没有任何明显的问题,但Valgrind会发现奇怪的泄漏。使用ldd代替valgrind确认它正在拾取错误的库文件。设置LD_LIBRARY_PATH正确地修复它,虽然正确的解决方案是增加库版本,因为如果你发生这种情况,它显然不再向后兼容。

当对象没有被正确销毁时,我也看到了这个问题,例如virtual函数缺少virtual析构函数的类。当将类放入指向基类的指针然后销毁时,只运行基类析构函数,泄漏派生类中分配的任何内容,例如示例中的std::string实例。这里的提示是检查哪个类正在使用泄漏的string,并按照类层次结构返回基类并确认它有一个明确的virtual析构函数,甚至是一个空的析构函数。我假设他们是隐含的,如果一个类中有virtual个函数但显然没有,并且GCC没有警告你这个。

答案 5 :(得分:0)

我遇到了这个问题,因为我的程序由于未捕获的异常而终止。显然,未捕获异常的处理程序不会清除所有内容。