为什么Valgrind指出我的std::map<T, T>实现会产生内存泄漏?

3

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
可能是由于使用了池分配器。来自Valgrind FAQ的解释:
我的程序使用C++ STL和string类。Valgrind在程序退出时报告涉及这些类的“仍可访问”内存泄漏,但实际上应该没有内存泄漏。 首先:放松心态,这可能不是一个错误,而是一个特性。许多C++标准库的实现使用它们自己的内存池分配器。相当多数量的已销毁对象的内存不会立即被释放并返回给操作系统,而是保留在池中以备将来重用。池在程序退出时不被释放的事实导致Valgrind将此内存报告为仍然可访问。但是,在退出()时不释放池的行为可能被称为库的一个错误。
阅读更多信息: Valgrind Faq
我可能是错的,因为我很匆忙,无法分析您的代码。

1

这个错误似乎不是来自你的代码,而是你正在使用的一个库。

Valgrind带有一些默认的错误抑制,但这可能不包括你正在使用的库。

错误检查工具会检测基本库(例如GNU C库和预安装在GNU/Linux系统上的X11客户端库)中的许多问题。你不能轻易修复它们,但你不想看到这些错误(是的,有很多!)。因此,Valgrind在启动时读取要抑制的错误列表。当系统构建时,./configure脚本会创建默认的抑制文件。

你可以创建自己的错误抑制列表,以忽略与你的代码无关的错误。

参见类似的SO问题 为什么Valgrind不喜欢我的glutCreateWindow用法?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接