Valgrind memory leak with std::string in std::map

早过忘川 提交于 2019-12-06 03:55:54

问题


Here is the output from 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)

This same error is repeated for every entry in the map.

main.cpp line 32 is:

    pilInpOpts input;

Line 12 of the pilInpOpts is part of the constructor:

#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 = "";
};

I found some posts in SO which said Valgrind may produce false positives. For example: std::string memory leak

Is this a false positive since std::string has all the constructors etc it needs to do this? Or should I change to use C character arrays in the map?


回答1:


One of the probable reasons of this behavior may be memory pooling in C++ standard library implementation.

From Valgrind faq:

Memory for quite a number of destructed objects is not immediately freed and given back to the OS, but kept in the pool(s) for later re-use. The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. The behaviour not to free pools at the exit could be called a bug of the library though.

You can set GLIBCXX_FORCE_NEW environment variable before running your app to force STL to free memory as soon as possible.

See also these links on details of libstdc++ memory allocator implementation:

  • https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.memory_leaks
  • https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html#debug.memory



回答2:


I've had similar issues with strings, and if I recall correctly, I was able to get rid of the errors by specifically implementing a destructor for the container class. For a map, you'll need to make an iterator, then explicitly delete the elements of iterator->first and iterator->second inside a loop for the size of the map.



来源:https://stackoverflow.com/questions/24457098/valgrind-memory-leak-with-stdstring-in-stdmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!