I can't clear the map memory (I checked by Valgrind).
#include <map>
class testMap {
public:
testMap(){}
~testMap();
void insert_map(int, int);
private:
std::map<int,int> _map;
};
void testMap::insert_map(int i, int j){
_map.insert( pair<int, int>(i,j));
}
I tried _map.clear()
, erase()
, deleted _map->second
manually but not still no luck.
Thanks for all replies. Actually map
alone is not a problem but map
with a singleton is causing a leak. What's wrong with the code below?
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include "Object.h"
#include<boost/smart_ptr.hpp>
using namespace std;
class Singleton {
public:
// A wrapper around Object class
class object
{
public:
object() : _object(new Object())
{}
Object get(void)
{ return _object.get(); }
private:
boost::shared_ptr<Object> _object;
};
object insert_new(const std::string key)
{
_object_maps.insert( pair<string,object>( key, object() ));
return _object_maps.find( key )->second;
//_test_object = object();
//return _test_object; // Leak goes away if I don't use map.
}
static Singleton* Instance();
void Print();
protected:
Singleton(){}
~Singleton();
private:
static Singleton* _instance;
std::map<std::string, object > _object_maps;
object _test_object;
};
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
if( _instance ==0 )
{
_instance = new Singleton();
}
return _instance;
}
void Singleton::Print() {
std::cout << " Hi I am a singleton object" << std::endl;
}
Singleton::~Singleton()
{
_object_maps.clear();
}
From another code I was calling by
Singleton::object _test_object(Singleton::Instance()->insert_new("TEST"));
Is there a problem? I am getting a Valgrind error, like
==19584== 17 bytes in 1 blocks are possibly lost in loss record 31,429 of 52,291
==19584== at 0x69A1642: operator new(unsigned int) (vg_replace_malloc.c:255)
==19584== by 0x772CB0A: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.8)
==19584== by 0x772D904: ??? (in /usr/lib/libstdc++.so.6.0.8)
==19584== by 0x772DB16: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.8)
==19584== by 0xBF1BC17: test::test() (test.C:34)
==19584== by 0xBF1DB66: G__testDict_143_0_1(G__value*, char const*, G__param*, int) (testDict.C:190)
==19584== by 0x70EA4E5: Cint::G__ExceptionWrapper(int (*)(G__value*, char const*, G__param*, int), G__value*, char*, G__param*, int) (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71EF2E4: G__call_cppfunc (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71C0095: G__interpret_func (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71AF883: G__getfunction (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71D8CC1: G__new_operator (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x718D07F: G__getexpr (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x717724E: G__define_var (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71FDEC6: G__defined_type (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x7201A6D: G__exec_statement (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71BF6C8: G__interpret_func (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x71AF62F: G__getfunction (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x718437D: G__getitem (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x7189F12: G__getexpr (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
==19584== by 0x719713F: G__calc_internal (in /afs/rhic.bnl.gov/@sys/opt/phenix/root-5.17.01/lib/libCint.so)
The best approach to checking for the existence of a memory leak in your application is by looking at your RAM usage and investigating the total amount of memory been used versus the total amount available. Evidently, it is advisable to obtain snapshots of your memory's heap dump while in a production environment.
Memory leaks are a common error in programming, especially when using languages that have no built in automatic garbage collection, such as C and C++. Typically, a memory leak occurs because dynamically allocated memory has become unreachable.
A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.
Very dangerous. Memory leaks in the kernel level lead to serious system stability issues. Kernel memory is very limited compared to user land memory and should be handled cautiously.
Short answer:
you explicitly declared but not defined the destructor (forgot {}
).
Long answer:
{}
in class destructor and std::
in front of pair
.Corrected and completed with main
:
#include <map>
class testMap {
public:
testMap() {}
~testMap() {};
void insert_map(int, int);
private:
std::map<int,int> _map;
};
void testMap::insert_map(int i, int j) {
_map.insert(std::pair<int, int>(i,j));
}
int main() {
testMap t;
t.insert_map(12, 34);
return 0;
}
Compiled on 32-bit Ubuntu 11.04:
g++ leak.cpp -o leak
Run under valgrind
supervision:
valgrind ./leak
==20773== Memcheck, a memory error detector
==20773== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20773== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==20773== Command: ./leak
==20773==
==20773==
==20773== HEAP SUMMARY:
==20773== in use at exit: 0 bytes in 0 blocks
==20773== total heap usage: 1 allocs, 1 frees, 24 bytes allocated
==20773==
==20773== All heap blocks were freed -- no leaks are possible
==20773==
==20773== For counts of detected and suppressed errors, rerun with: -v
==20773== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6)
No memory leakage.
Probably your compiler auto-defines a completely empty class destructor (because of missing {}
), not auto-calling anymore on exit the private member map destructor.
Hope it helps :)
Try:
{
std::map<int,int> empty_map;
empty_map.swap(_map);
}
(At least, this is the usual way to convince a standard library container actually to release its memory.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With