Pergunta

Existe alguma dica / truques para encontrar referências cíclicas de shared_ptr de?

Este é um exmaple do que eu estou tentando encontrar -. Infelizmente eu não consigo encontrar o loop no meu código

struct A
{
  boost::shared_ptr<C> anC;
};

struct B
{
  boost::shared_ptr<A> anA;
};

struct C
{
  boost::shared_ptr<B> anB;
};
Foi útil?

Solução 4

Eu usei uma combinação das mensagens acima. Eu usei um profiler de memória, veio com alguns ciclos suspeitos e quebrou aqueles usando weak_ptr do.

Eu usei o construído em detecção de vazamento de memória CRT antes, mas, infelizmente, no meu caso há vários singletons estáticos que não entendo desalocada até módulo de descarga que eu acredito que é após os detectores CRT ciclo de vida. Basicamente, ele dá um monte de vômito que são falsos positivos.

Outras dicas

Eu recomendo usar Valgrind . Quando encerrar o processo, ele vai mostrar toda a memória vazada. A menos que seu desligamento alguma maneira quebra o ciclo, quaisquer ciclos deve aparecer como memória vazada e Valgrind vai lhe dizer onde em seu código a memória foi originalmente atribuído a partir.

Eu estava encarregado do projeto de um sistema de risco de crédito uma vez (em C ++, no entanto, que não é relevante). Essas coisas são realmente grandes gráficos com risco alocado nos nós. Tivemos uma heurística simples para descobrir se estávamos em um ciclo - se percorrido mais de 500 vezes (I esquecer o número exato - era configurável), a resposta foi sim. A maioria dos esquemas de detecção ciclo de confiar em heurísticas como este.

Eu tive problemas semelhantes no passado -. Vazamentos de memória devido à shared_ptr referências cíclicas que foi detectado durante meses

Cuidado com os "caches". Eu tenho um objeto (chamado de Let It "Factory") que movimentou os itens ( "widgets"). Widgets tinha a propriedade de ser A) Imutável, e B) Tinha um shared_ptr<Factory> ao seu criador (por vezes criados outros widgets, etc). Tudo funcionou bem, até que eu adicionei um cache Widget para Factory - uma vez que os Widgets eram imutáveis, fazia sentido para armazenar em cache-los, para devolver o mesmo toda vez Widget foram solicitadas. Meu cache era um esconderijo de shared_ptr<Widget>, de modo instantâneo vazamento em silêncio. As correções são óbvias, então eu não vou entrar em-los.

Em última análise, eu era capaz de inclinar-se sobre a plataforma que eu estava usando para detectar tais vazamentos de memória do CRT. CRT do Visual Studio tem memória vazada detecção e reporte, que eu habilitado no meu programa de teste para evitar regressões:

int main()
{
    // code code code
    // code code code

#ifdef _MSC_VER
    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
    _CrtDumpMemoryLeaks();
#endif
}

GCC provavelmente tem relatórios de vazamento básica similar, mas eu não sei o que é.

Eu acho que a resposta mais simples é que há somente tanto ponteiros inteligentes pode fazer por você:

Eu sugiro gravação sempre que você make um loop, (fácil se você criar todos os três objetos de uma só vez, mais complicado caso contrário ...), e depois verificar que o registro onde você excluir / objetos desvincular, ou apenas periodicamente se isso não é possível.

Você poderia implementar algum tipo de depuração interface que retorna uma lista de shared_ptrs pertencentes a este objeto. Você precisaria fazer isso para todas as classes armazenadas em um shared_ptr. Agora você tem um gráfico genérico que você pode percorrer, e pode usar algoritmos de detecção de ciclo nele. Acredito Tarjan está fortemente ligado algoritmo componente trabalho poder para isso, mas a teoria dos grafos não é o meu forte.

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