Memory leak in deleting TTree

Hi! :slight_smile:
I am still developing my own application based on ROOT framework. I use the TTree class to loop on thousands of files, each of which containing data organized within a tree. Unless the application runs over a few files, sooner or later the program crashes :frowning: with the following message:

terminate called after throwing an instance of 'std::bad_alloc' what(): St9bad_alloc
I checked the memory leakages due to my errors, but there is no leak from my lines of code. The only leaks seem to be due to the ROOT libraries which I link to :unamused:.
I tried to isolate the problem with a simple dummy prog:

#include "TTree.h" int main() { TTree *t= new TTree("TestTree","A test tree"); delete t; return 0; }
I compiled it with:

and here is the output of the valgrind check:

[roberto@atlas9 ROOT_CERN]$ valgrind --leak-check=yes ./test.exe ==18672== Memcheck, a memory error detector. ==18672== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==18672== Using LibVEX rev 1575, a library for dynamic binary translation. ==18672== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==18672== Using valgrind-3.1.1, a dynamic binary instrumentation framework. ==18672== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==18672== For more details, rerun with: -v ==18672== ==18672== ==18672== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 51 from 2) ==18672== malloc/free: in use at exit: 1,193,996 bytes in 25,798 blocks. ==18672== malloc/free: 62,206 allocs, 36,408 frees, 2,863,721 bytes allocated. ==18672== For counts of detected errors, rerun with: -v ==18672== searching for pointers to 25,798 not-freed blocks. ==18672== checked 7,394,544 bytes. ==18672== ==18672== 1 bytes in 1 blocks are definitely lost in loss record 1 of 81 ==18672== at 0x4004405: malloc (vg_replace_malloc.c:149) ==18672== by 0x47A00FB: G__store_dictposition (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x4720209: G__register_sharedlib (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x47A9048: G__RegisterLibrary (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x471B80B: G__call_setup_funcs (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x471BA78: G__main (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x471D7B7: G__init_cint (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x41DDA34: TCint::ResetAll() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41DDBE2: TCint::TCint(char const*, char const*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4158351: TROOT::TROOT(char const*, char const*, void (**)()) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4159105: ROOT::GetROOT() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x417D7F4: TTimer::Reset() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== ==18672== ==18672== 55 bytes in 1 blocks are definitely lost in loss record 21 of 81 ==18672== at 0x4004405: malloc (vg_replace_malloc.c:149) ==18672== by 0x472023C: G__register_sharedlib (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x47A9048: G__RegisterLibrary (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x471A085: G__add_setup_func (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x5C3CAB0: G__cpp_setup_initG__Thread::G__cpp_setup_initG__Thread() (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3B976: __static_initialization_and_destruction_0(int, int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3B9D8: _GLOBAL__I__ZN4ROOT20GenerateInitInstanceEPK13TConditionImp (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3DE44: (within /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C1D164: (within /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x936717: _dl_init (in /lib/ld-2.3.4.so) ==18672== by 0x92A7FE: (within /lib/ld-2.3.4.so) ==18672== ==18672== ==18672== 60 (28 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 81 ==18672== at 0x4004405: malloc (vg_replace_malloc.c:149) ==18672== by 0x4741C8F: G__memfunc_setup_imp (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x4742359: G__memfunc_setup (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x5B2BCC4: G__cpp_setup_funcG__Math (in /home/roberto/ROOT_CERN/root_compiled/lib/libMathCore.so) ==18672== by 0x5B2BF3E: G__cpp_setupG__Math (in /home/roberto/ROOT_CERN/root_compiled/lib/libMathCore.so) ==18672== by 0x471B85A: G__call_setup_funcs (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x5B2E8BC: _GLOBAL__I__ZN4ROOT20GenerateInitInstanceEPK8TComplex (in /home/roberto/ROOT_CERN/root_compiled/lib/libMathCore.so) ==18672== by 0x5BBA420: (within /home/roberto/ROOT_CERN/root_compiled/lib/libMathCore.so) ==18672== by 0x5AD8474: (within /home/roberto/ROOT_CERN/root_compiled/lib/libMathCore.so) ==18672== by 0x936717: _dl_init (in /lib/ld-2.3.4.so) ==18672== by 0x92A7FE: (within /lib/ld-2.3.4.so) ==18672== ==18672== ==18672== 61 (60 direct, 1 indirect) bytes in 1 blocks are definitely lost in loss record 31 of 81 ==18672== at 0x4004405: malloc (vg_replace_malloc.c:149) ==18672== by 0x47201F7: G__register_sharedlib (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x47A9048: G__RegisterLibrary (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x471A085: G__add_setup_func (in /home/roberto/ROOT_CERN/root_compiled/lib/libCint.so) ==18672== by 0x5C3CAB0: G__cpp_setup_initG__Thread::G__cpp_setup_initG__Thread() (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3B976: __static_initialization_and_destruction_0(int, int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3B9D8: _GLOBAL__I__ZN4ROOT20GenerateInitInstanceEPK13TConditionImp (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3DE44: (within /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C1D164: (within /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x936717: _dl_init (in /lib/ld-2.3.4.so) ==18672== by 0x92A7FE: (within /lib/ld-2.3.4.so) ==18672== ==18672== ==18672== 93 bytes in 4 blocks are possibly lost in loss record 33 of 81 ==18672== at 0x4004790: operator new(unsigned) (vg_replace_malloc.c:164) ==18672== by 0x2D94A44: std::string::_Rep::_S_create(unsigned, unsigned, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.3) ==18672== by 0x2D97484: (within /usr/lib/libstdc++.so.6.0.3) ==18672== by 0x2D975B5: std::string::string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.3) ==18672== by 0x41B74D2: TClass::AddClass(TClass*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41B79A7: TClass::Init(char const*, short, std::type_info const*, TVirtualIsAProxy*, void (*)(void*, TMemberInspector&, char*), char const*, char const*, int, int, bool) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41B8813: TClass::TClass(char const*, short, std::type_info const&, TVirtualIsAProxy*, void (*)(void*, TMemberInspector&, char*), char const*, char const*, int, int, bool) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x42B2484: TQClass::TQClass(char const*, short, std::type_info const&, TVirtualIsAProxy*, void (*)(void*, TMemberInspector&, char*), char const*, char const*, int, int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x42B23DD: ROOT::TQObjectInitBehavior::CreateClass(char const*, short, std::type_info const&, TVirtualIsAProxy*, void (*)(void*, TMemberInspector&, char*), char const*, char const*, int, int) const (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41C5F48: ROOT::TGenericClassInfo::GetClass() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x42BE128: TQObject::Class() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4152049: TQObject::IsA() const (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== ==18672== ==18672== 200 bytes in 1 blocks are definitely lost in loss record 39 of 81 ==18672== at 0x4004BBE: operator new[](unsigned) (vg_replace_malloc.c:197) ==18672== by 0x418F846: TArrayI::Set(int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4123951: TColor::SetPalette(int, int*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41654BD: TStyle::SetPalette(int, int*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4165A37: TStyle::Reset(char const*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4166700: TStyle::TStyle(char const*, char const*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4166F07: TStyle::BuildStyles() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4158DEF: TROOT::TROOT(char const*, char const*, void (**)()) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4159105: ROOT::GetROOT() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x417D7F4: TTimer::Reset() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x417DED6: TTimer::TTimer(long, bool) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x417E435: _GLOBAL__I_gSingleShotCleaner (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== ==18672== ==18672== 448 bytes in 2 blocks are possibly lost in loss record 45 of 81 ==18672== at 0x4004790: operator new(unsigned) (vg_replace_malloc.c:164) ==18672== by 0x415CD35: TStorage::ObjectAlloc(unsigned) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x8048AD0: TObject::operator new(unsigned) (TObject.h:156) ==18672== by 0x42B23AF: ROOT::TQObjectInitBehavior::CreateClass(char const*, short, std::type_info const&, TVirtualIsAProxy*, void (*)(void*, TMemberInspector&, char*), char const*, char const*, int, int) const (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41C5F48: ROOT::TGenericClassInfo::GetClass() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x42BE128: TQObject::Class() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4152049: TQObject::IsA() const (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x414E8ED: TQObject::Emit(char const*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x414F072: TQObject::~TQObject() (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x417E28C: __tcf_0 (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x9727E7: __cxa_finalize (in /lib/tls/libc-2.3.4.so) ==18672== by 0x4111CED: (within /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== ==18672== ==18672== 120,385 bytes in 2,718 blocks are possibly lost in loss record 77 of 81 ==18672== at 0x4004BBE: operator new[](unsigned) (vg_replace_malloc.c:197) ==18672== by 0x415D61B: TStringRef::GetRep(int, int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x415D913: TString::TString(char const*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4197DA7: TClassTable::Add(char const*, short, std::type_info const&, void (*)(), int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x4197E30: ROOT::AddClass(char const*, short, std::type_info const&, void (*)(), int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41C84B4: ROOT::TDefaultInitBehavior::Register(char const*, short, std::type_info const&, void (*)(), int) const (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41C565D: ROOT::TGenericClassInfo::Init(int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x41C720D: ROOT::TGenericClassInfo::TGenericClassInfo(char const*, int, char const*, int, std::type_info const&, ROOT::TInitBehavior const*, void (*)(), TVirtualIsAProxy*, int, int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libCore.so) ==18672== by 0x5C24DC6: ROOT::GenerateInitInstanceLocal(TConditionImp const*) (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3B773: __static_initialization_and_destruction_0(int, int) (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3B9D8: _GLOBAL__I__ZN4ROOT20GenerateInitInstanceEPK13TConditionImp (in /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== by 0x5C3DE44: (within /home/roberto/ROOT_CERN/root_compiled/lib/libThread.so) ==18672== ==18672== LEAK SUMMARY: ==18672== definitely lost: 344 bytes in 5 blocks. ==18672== indirectly lost: 33 bytes in 4 blocks. ==18672== [u] possibly lost: 120,926 bytes in 2,724 blocks[/u]. ==18672== still reachable: 1,072,693 bytes in 23,065 blocks. ==18672== suppressed: 0 bytes in 0 blocks. ==18672== Reachable blocks (those to which a pointer was found) are not shown. ==18672== To see them, rerun with: --show-reachable=yes
Is it possible to avoid the โ€œ120,385 bytes in 2,718 blocksโ€ memory leak? I donโ€™t know, maybe by compiling differently or by using some other libs.
Thanks for your patience.
Roberto

This is not a memory leak. At run time the dictionaries for the referenced classes are loaded in memory. We never delete these dictionaries.

Rene

Hi Roberto,

see root.cern.ch/viewvc/trunk/etc/valgrind-root.supp for a valgrind suppression file that will get rid of most (all?) of the valgrind reports that should be ignored.

Cheers, Axel.

Yes, actually all the โ€œleaksโ€ that I found are known to you.
Ok. I will try to work around the problem.
Thanks!
Roberto

==6265== Memcheck, a memory error detector. ==6265== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==6265== Using LibVEX rev 1575, a library for dynamic binary translation. ==6265== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==6265== Using valgrind-3.1.1, a dynamic binary instrumentation framework. ==6265== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==6265== For more details, rerun with: -v ==6265== ==6265== ==6265== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 51 from 2) ==6265== malloc/free: in use at exit: 1,194,099 bytes in 25,798 blocks. ==6265== malloc/free: 62,205 allocs, 36,407 frees, 2,864,101 bytes allocated. ==6265== For counts of detected errors, rerun with: -v ==6265== searching for pointers to 25,798 not-freed blocks. ==6265== checked 7,395,400 bytes. ==6265== ==6265== LEAK SUMMARY: ==6265== definitely lost: 377 bytes in 9 blocks. ==6265== possibly lost: 121,029 bytes in 2,724 blocks. ==6265== still reachable: 1,072,693 bytes in 23,065 blocks. ==6265== suppressed: 0 bytes in 0 blocks. ==6265== Use --leak-check=full to see details of leaked memory.