Por que Valgrind afirmando que minha implementação do std :: map produz um vazamento de memória?

StackOverflow https://stackoverflow.com/questions/766080

  •  12-09-2019
  •  | 
  •  

Pergunta

Valgrind está a emitir o seguinte:

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

O que isso poderia média?

//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());
Foi útil?

Solução

É provavelmente por causa de um alocador de piscina. De Valgrind FAQ:

O meu programa usa o C ++ STL e aulas de cordas. relatórios Valgrind vazamentos de memória 'ainda alcançáveis' envolvendo essas classes na saída do o programa, mas não deve haver nenhum.

Primeiro de tudo: relaxar, provavelmente não é um erro, mas uma característica. Muitos implementações padrão de C ++ bibliotecas usar seu próprio pool de memória allocators. Memória para um grande número de objetos Destructed não é imediatamente libertados e devolvidos aos o sistema operacional, mas manteve na piscina (s) para depois re-uso. O fato de que as piscinas não são libertados na saída () do programa causa Valgrind a informar que esta memória como ainda acessível. o comportamento não piscinas gratuitas no exit () poderia ser chamado de um bug do biblioteca embora.

Leia mais em: Valgrind Faq

Posso estar errado, como eu estou com pressa e eu não posso analisar seu código.

Outras dicas

O erro não parecem vir de seu código, mas uma biblioteca que você está usando.

Valgrind vem com alguma supressão de erro padrão, mas que provavelmente não cobre a biblioteca que você está usando.

As ferramentas de verificação de erros detectar inúmeros problemas nas bibliotecas de base, tais como a biblioteca GNU C, e as bibliotecas do cliente X11, que vêm pré-instalados em seu sistema GNU / Linux. Você não pode facilmente corrigir isso, mas você não quer ver estes erros (e sim, há muitos!) Então Valgrind lê uma lista de erros para suprimir na inicialização. Um arquivo de supressão padrão é criado pelo script ./configure quando o sistema é construído.

Você pode criar seu próprio supressões de erro que você sabe são irrelevantes para o seu código.

Veja o semelhante SO pergunta Por que Valgrind não como o meu uso de glutCreateWindow?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top