Почему Valgrind заявляет, что моя реализация std :: map <T, T> вызывает утечку памяти? - PullRequest
3 голосов
/ 20 апреля 2009

Valgrind выводит следующее:

==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)

Что бы это могло значить?

//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());

Ответы [ 2 ]

5 голосов
/ 20 апреля 2009

Это, вероятно, из-за распределителя пула. От Valgrind FAQ:

Моя программа использует C ++ STL и строковые классы. Valgrind сообщает «все еще достижимые» утечки памяти с участием этих классов на выходе программа, но там должно быть доли не имеет.

Прежде всего: расслабься, наверное, нет ошибка, но особенность. Много реализации стандарта C ++ библиотеки используют собственный пул памяти распределители. Память на целый ряд разрушенных объектов не немедленно освобожден и возвращен ОС, но хранится в пуле (ях) для позже повторно. Тот факт, что бассейны не освобождаются на выходе () программа заставит Valgrind сообщить об этом память все еще достижима. поведение не освободить пулы на exit () можно назвать ошибкой библиотека хотя.

Подробнее на: Valgrind Faq

Возможно, я ошибаюсь, так как спешу и не могу проанализировать ваш код.

1 голос
/ 20 апреля 2009

Ошибка, похоже, не в вашем коде, а в используемой вами библиотеке.

Valgrind поставляется с некоторым подавлением ошибок по умолчанию, но это, вероятно, не распространяется на используемую вами библиотеку.

Инструменты проверки ошибок обнаруживают многочисленные проблемы в базовых библиотеках, таких как библиотека GNU C и клиентские библиотеки X11, которые предварительно установлены в вашей системе GNU / Linux. Вы не можете легко исправить это, но вы не хотите видеть эти ошибки (и да, их много!), Поэтому Valgrind читает список ошибок, которые нужно устранить при запуске. Файл подавления по умолчанию создается скриптом ./configure при сборке системы.

Вы можете создать свои собственные средства подавления ошибок , которые, как вы знаете, не имеют отношения к вашему коду.

См. Аналогичный вопрос SO Почему Valgrind не нравится мое использование glutCreateWindow?

...