【问题标题】:std::string causing memory leaksstd::string 导致内存泄漏
【发布时间】:2018-10-08 16:37:26
【问题描述】:

我遇到了我的应用程序出现内存泄漏的情况。运行 valgrind 后,我似乎遇到了与 std::string 相关的内存泄漏:

 ==20274== 34 bytes in 1 blocks are definitely lost in loss record 34 of 140
 ==20274==    at 0x4C29DB5: operator new(unsigned long) (vg_replace_malloc.c:332)
 ==20274==    by 0x7F843C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13)
 ==20274==    by 0x7F84DE4: ??? (in /usr/lib64/libstdc++.so.6.0.13)
 ==20274==    by 0x7F84F32: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13)
 ==20274==    by 0xA50CC71: __static_initialization_and_destruction_0(int, int) (filename.cpp:22)
 ==20274==    by 0xA50D03F: _GLOBAL__sub_I_filename.cpp (filename.cpp:112)
 ==20274==    by 0x400E9CE: _dl_init (in /lib64/ld-2.12.so)
 ==20274==    by 0x4000B69: ??? (in /lib64/ld-2.12.so)

有问题的代码是:

在文件名.h 中:

 extern std::string aString;

在文件名.cpp 中:

 std::string aString = "a string";

另外值得注意的是,这是在一个单独的命名空间中,即

 namespace aNamespace {
      //...
      std::string aString; // in extern in .h
      //...
 }

代码中的每个地方,它(当然)都被引用为:

 aNamespace::aString;

而且,据我所知,它永远不会被重置,并且用作常量引用或初始化另一个字符串。

是否存在 std::string 会导致内存泄漏的情况?

编辑:

valgrind 输出的相关部分:

 ==20274==    by 0x400EFBB: _dl_fini (in /lib64/ld-2.12.so)
 ==20274==    by 0x88DAA01: exit (in /lib64/libc-2.12.so)
 ==20274==    by 0x88C3D26: (below main) (in /lib64/libc-2.12.so)

这是在发出退出调用吗?是标准出口(0)吗?

【问题讨论】:

  • 我假设程序退出而不是崩溃/中止?
  • 你使用什么 std::string 实现?
  • 你能提供一个minimal reproducible example吗? std::string 不应该泄漏,因为 tat 会破坏很多代码库。
  • 注意 valgrind 可以报告来自 std::string 的泄漏,如果包含 std::string 的其他对象正在泄漏。如果有其他对象泄漏,请检查 valgrind 日志。修复它并再次检查。
  • @basil 我们需要的是可以复制并粘贴到我们自己的编译器中的东西,它会显示内存泄漏。现在我们只能告诉你这很可能不是std::string的错。

标签: c++ memory-leaks stl valgrind


【解决方案1】:

如果在程序终止时仍有一些堆分配的内存,但没有变量持有指向的指针,Valgrind 会产生这种消息。 std::string 在其构造函数中分配内存以提供字符存储。析构函数应该释放内存。

我的猜测是应用程序使用 exit(0) 左右终止。在这种情况下,堆栈不会展开,也不会调用析构函数。

【讨论】:

  • 我编辑了一个相关的错误,我想你可能是对的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
  • 2011-03-26
  • 1970-01-01
  • 2014-08-18
相关资源
最近更新 更多