Valgrind检测到std::map中的std::string存在内存泄漏问题

5

这是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字符数组在map中?


2
你能否添加关于编译器、编译标志、平台和valgrind版本的信息?我尝试根据您的描述创建一个最小化的示例,但在这种情况下,valgrind根本没有报告任何内存错误。也许您可以将问题简化为一个最小的、自包含的示例,以展示该问题。 - halfflat
2
发布一个 MCVE - M.M
2个回答

5
这种行为的可能原因之一可能是C++标准库实现中的内存池。

来自Valgrind faq

相当数量的被销毁对象的内存不会立即释放并返回给操作系统,而是保留在内存池中以备后续重用。程序退出时未释放内存池导致Valgrind将其报告为仍然可达的内存。尽管如此,不释放内存池的行为可以被称作库的一个bug。

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

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


1

我曾经遇到过与字符串类似的问题,如果我没记错的话,我成功通过为容器类专门实现一个析构函数来消除了错误。对于一个 map,你需要创建一个迭代器,然后在循环中显式删除 iterator->first 和 iterator->second 的元素,直到 map 的大小。


如果你绝对必须修复这个错误(就像我的情况一样,因为代码被用于我其中一个课程的通过考试,并且需要 Valgrind 没有 0 内存泄漏),这是我迄今发现的唯一解决此问题的方法。 - mdhansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接