Warum ist Valgrind besagt, dass meine Implementierung von std :: map erzeugt ein Speicherleck?
Frage
Valgrind ausgibt wie folgt vor:
==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());
Lösung
Es ist wahrscheinlich wegen eines Pool Allocator. Von Valgrind FAQ:
Mein Programm verwendet den C ++ STL und String-Klassen. valgrind berichtet ‚Nach wie vor erreichbar‘ Speicherlecks Einbeziehung dieser Klassen am Ausgang das Programm, aber es sollte sein keine.
Zu allererst: entspannen, ist es wahrscheinlich nicht Bug, sondern ein Feature. Viele Implementationen der C ++ Standard Bibliotheken nutzen, um ihren eigenen Speicherpool Verteilern. Speicher für eine ganze Zahl zerstörter Objekte nicht befreit und sofort zurück gegeben zu das Betriebssystem, sondern im Pool gehalten (e) für später wiederverwenden. Die Tatsache, dass die Pools nicht am Ausgang befreit () der Programm führen Valgrind dies melden Speicher als noch erreichbar. Das Verhalten nicht zu freien Pools in der exit () konnte einen Fehler von der heißen obwohl Bibliothek.
Lesen Sie mehr unter: Valgrind Faq
Ich kann falsch sein, wie ich in Eile bin und ich kann Ihren Code nicht analysieren.
Andere Tipps
Der Fehler scheint nicht aus dem Code zu kommen, aber eine Bibliothek Sie verwenden.
Valgrind kommt mit einiger Standardfehlerunterdrückung, aber das wahrscheinlich gilt nicht für die Bibliothek, die Sie verwenden.
Die Fehlerprüfung Tools erkennen zahlreiche Probleme in den Basisbibliotheken, wie die GNU-C-Bibliothek und die X11-Client-Bibliotheken, die auf Ihrem GNU / Linux-System vorinstalliert. Sie können diese nicht leicht beheben, aber Sie wollen nicht, diese Fehler sehen (und ja, es gibt viele!) So Valgrind liest eine Liste der Fehler beim Start zu unterdrücken. Eine Standard-Unterdrückung Datei wird vom ./configure-Script erstellt, wenn das System aufgebaut wird.
Sie können Ihre eigenen Fehler Unterdrückungen erstellen dass Sie wissen, um Ihren Code nicht relevant sind.
Sehen Sie die ähnliche Frage SO Warum Valgrind nicht mein mögen Verwendung von glutCreateWindow?