2009-04-19 5 views
3

Valgrind wird die Ausgabe des folgenden:Warum gibt Valgrind an, dass meine Implementierung von std :: map <T, T> ein Speicherleck erzeugt?

==14446== 2,976 (176 direct, 2,800 indirect) bytes in 2 blocks are definitely lost in loss record 23 of 33 
==14446== at 0x4C2506C: operator new(unsigned long) (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) 
==14446== by 0x41C487: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::allocate(unsigned long, void const*) (new_allocator.h:92) 
==14446== by 0x41C4AB: std::_Rb_tree<unsigned, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn>, std::_Select1st<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::_M_get_node() (stl_tree.h:357) 
==14446== by 0x41C915: std::_Rb_tree<unsigned, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn>, std::_Select1st<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::_M_create_node(std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> const&) (stl_tree.h:366) 
==14446== by 0x5036E9A: std::_Rb_tree<unsigned, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn>, std::_Select1st<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::_M_insert_(std::_Rb_tree_node_base const*, std::_Rb_tree_node_base const*, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> const&) (stl_tree.h:852) 
==14446== by 0x5037027: std::_Rb_tree<unsigned, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn>, std::_Select1st<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::_M_insert_unique(std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> const&) (stl_tree.h:1148) 
==14446== by 0x5037227: std::_Rb_tree<unsigned, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn>, std::_Select1st<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::_M_insert_unique_(std::_Rb_tree_const_iterator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> const&) (stl_tree.h:1188) 
==14446== by 0x50375CD: std::map<unsigned, vimrid::imaging::ImageMatrixColumn, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::insert(std::_Rb_tree_iterator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> >, std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> const&) (stl_map.h:496) 
==14446== by 0x50376DE: std::map<unsigned, vimrid::imaging::ImageMatrixColumn, std::less<unsigned>, std::allocator<std::pair<unsigned const, vimrid::imaging::ImageMatrixColumn> > >::operator[](unsigned const&) (stl_map.h:419) 
==14446== by 0x5036A43: vimrid::imaging::ImageMatrixRow::operator[](unsigned) (ImageMatrixRow.cpp:10) 
==14446== by 0x5034BBB: vimrid::imaging::ImageMatrix::_getRotatedCopy(double, vimrid::imaging::ImageMatrix&) (ImageMatrix.cpp:151) 
==14446== by 0x503350A: vimrid::imaging::processing::ImageFilter& vimrid::imaging::ImageMatrix::GetRotatedCopy<vimrid::imaging::processing::ImageFilter>(double) (ImageMatrix.h:48) 

Was könnte das wohl bedeuten?

//ImageMatrixRow.cpp:8-11 
ImageMatrixColumn &ImageMatrixRow::operator[](VUInt32 columnIndex) 
{ 
    return columns[columnIndex]; 
} 

//ImageMatrix.cpp:151 
target[x][y][0] = source[roundX][roundY][0]; 

//ImageMatrix.h:48 
return *(T*)&_getRotatedCopy(degrees, CopyDimensions()); 

Antwort

5

Es ist wahrscheinlich wegen eines Pool-Allokators. Von Valgrind FAQ:

Mein Programm verwendet die C++ STL und String-Klassen. Valgrind Berichte "immer noch erreichbar" Speicherlecks mit diesen Klassen am Ausgang von das Programm, aber es sollte keine sein.

Vor allem: entspannen, es ist wahrscheinlich nicht ein Bug, aber eine Funktion. Viele Implementierungen der C++ - Standard Bibliotheken verwenden ihre eigenen Speicherpool Allokatoren. Speicher für eine ganze Zahl von zerstörten Objekten ist nicht sofort freigegeben und an das OS zurückgegeben, aber in den Pool (s) für später wieder verwendet. Die Tatsache, dass die Pools nicht am exit() des -Programms freigegeben werden, bewirkt, dass Valgrind diesen -Speicher als noch erreichbar meldet. Das Verhalten, nicht Pools bei exit() zu befreien, könnte ein Fehler der Bibliothek obwohl genannt werden.

Lesen Sie mehr unter: Valgrind Faq

Ich kann falsch sein, wie ich in Eile bin und ich kann Ihren Code nicht analysieren.

1

Der Fehler scheint nicht von Ihrem Code zu stammen, sondern von einer Bibliothek, die Sie verwenden.

Valgrind wird mit einer Standard-Fehlerunterdrückung ausgeliefert, die aber wahrscheinlich nicht die von Ihnen verwendete Bibliothek abdeckt.

Die Fehlerüberprüfungstools erkennen zahlreiche Probleme in den Basisbibliotheken, z. B. der GNU C-Bibliothek und den X11-Clientbibliotheken, die auf Ihrem GNU/Linux-System vorinstalliert sind. Sie können diese nicht einfach beheben, aber Sie möchten diese Fehler nicht sehen (und ja, es gibt viele!) Also liest Valgrind eine Liste von Fehlern, die beim Start unterdrückt werden sollen. Eine Standardunterdrückungsdatei wird beim Erstellen des Systems vom Skript ./configure erstellt.

Sie können Ihre eigenen error suppressions erstellen, von denen Sie wissen, dass sie für Ihren Code irrelevant sind.

Siehe ähnliche Frage Why does Valgrind not like my usage of glutCreateWindow?