2010-06-08 104 views
10

我有一个问题有关的std :: string可能的内存泄漏的valgrind许多警告,像这样的:C++的std :: string池,调试版本?的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

检查FAQ描述被抑制。有关于“容器内存泄漏”的部分。你应该

  • 检查Valgrind的
  • 版本
  • 使用你的程序的调试版本(和未优化)
  • ,如果需要定义GLIBCXX_FORCE_NEW。 (这是一个环境变量,会影响你的程序的运行时的行为,而不是编译时#define如您所想。)
2

如果我没有记错,许多STL分配器实现某种记忆保持的。 IE浏览器不会立即释放分配的内存,而是保留并重用它。我的STL实现中分配的内存中valgrind肯定有很多误报。

我已经找到了解决这一问题的最佳方式是(简单)使用抑制文件。

0

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

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

0

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