【问题标题】:Valgrind memory leak with std::string in std::mapValgrind 内存泄漏与 std::map 中的 std::string
【发布时间】:2014-08-18 21:00:08
【问题描述】:

这是 Valgrind 的输出:

==6519==    at 0x4C25885: operator new(unsigned long) (vg_replace_malloc.c:319)
==6519==    by 0x4EE65D8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (new_allocator.h:104)
==6519==    by 0x4EE7CE0: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (basic_string.tcc:138)
==6519==    by 0x4EE80F7: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (basic_string.h:1725)
==6519==    by 0x41C399: pilInpOpts::pilInpOpts() (pilInpOpts.cpp:12)
==6519==    by 0x403A55: main (main.cpp:32)

地图中的每个条目都会重复同样的错误。

main.cpp 第 32 行是:

    pilInpOpts input;

pilInpOpts 的第 12 行是构造函数的一部分:

#include "pilInpOpts.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>


pilInpOpts::pilInpOpts() 
{
// create the map of options, put in alphabetical order to ease sorting
piloptmap.insert(std::pair<std::string, bool>("bforce",false));
piloptmap.insert(std::pair<std::string, bool>("coef",false));
piloptmap.insert(std::pair<std::string, bool>("dualjet",false));
piloptmap.insert(std::pair<std::string, bool>("flow",false));
piloptmap.insert(std::pair<std::string, bool>("gforce",false));
piloptmap.insert(std::pair<std::string, bool>("gpress",false));
piloptmap.insert(std::pair<std::string, bool>("matlab",false));
piloptmap.insert(std::pair<std::string, bool>("model",false));
piloptmap.insert(std::pair<std::string, bool>("out_shade",false));
piloptmap.insert(std::pair<std::string, bool>("out_shade_file",false));
piloptmap.insert(std::pair<std::string, bool>("press",false));
piloptmap.insert(std::pair<std::string, bool>("proc",false));
piloptmap.insert(std::pair<std::string, bool>("shade",false));
piloptmap.insert(std::pair<std::string, bool>("summary",false));
piloptmap.insert(std::pair<std::string, bool>("trans",false));
// need to define the default filepaths, this is needed because they are optional
platpath = "";
vehpath = "";
apppath = "";
dockpath = "";
};

我在 SO 中发现一些帖子说 Valgrind 可能会产生误报。例如:std::string memory leak

这是一个误报,因为 std::string 具有它需要执行此操作的所有构造函数等?或者我应该改成在地图中使用 C 字符数组?

【问题讨论】:

  • 您能否添加有关编译器、编译标志、平台和 valgrind 版本的信息?我试图根据您的描述创建一个最小的示例,但在这种情况下,valgrind 根本没有报告任何内存错误。也许您可以将您的问题简化为一个最小的、独立的示例来展示该问题。
  • 发布MCVE

标签: c++ valgrind stdstring stdmap


【解决方案1】:

此行为的一个可能原因可能是 C++ 标准库实现中的内存池。

来自Valgrind faq

大量被破坏对象的内存不是立即的 释放并返回给操作系统,但保留在池中以备后用 重复使用。池在出口处未释放的事实 程序导致 Valgrind 报告此内存仍可访问。这 不在出口释放池的行为可以称为错误 不过图书馆。

您可以在运行应用前设置GLIBCXX_FORCE_NEW环境变量,强制STL尽快释放内存。

有关 libstdc++ 内存分配器实现的详细信息,另请参阅以下链接:

【讨论】:

    【解决方案2】:

    我在字符串方面也遇到过类似的问题,如果我没记错的话,我可以通过专门为容器类实现一个析构函数来消除这些错误。对于地图,您需要创建一个迭代器,然后根据地图的大小在循环内显式删除 iterator->first 和 iterator->second 的元素。

    【讨论】:

    • 如果您绝对必须修复错误(就像我的情况,因为代码在我的一个类中被用于 passoff 并且需要 Valgrind 的 0 内存泄漏),这是唯一的方法到目前为止,我已找到解决此问题的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2011-03-26
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 2018-02-03
    相关资源
    最近更新 更多