Domanda

C'è qualche consiglio / trucchi per la ricerca di riferimenti ciclici di shared_ptr di?

Questa è un'exmaple di quello che sto cercando di trovare -. Purtroppo non riesco a trovare l'anello nel mio codice

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

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

struct C
{
  boost::shared_ptr<B> anB;
};
È stato utile?

Soluzione 4

Ho usato una combinazione dei posti di cui sopra. Ho usato un profiler di memoria, si avvicinò con alcuni cicli sospetti e quelli rotto utilizzando weak_ptr di.

Ho usato il costruito nel rilevamento di perdite di memoria CRT prima, ma purtroppo nel mio caso ci sono molti single statiche che non ottenete deallocato fino modulo di scarico che credo sia dopo il ciclo di vita rilevatori CRT. Fondamentalmente si dà un sacco di vomitare che sono falsi positivi.

Altri suggerimenti

Mi consiglia di utilizzare Valgrind . Quando si arresta il processo, che vi mostrerà tutta la memoria trapelato. A meno che il vostro arresto interrompe in qualche modo il ciclo, eventuali cicli dovrebbero mostrare come memoria persa e Valgrind vi dirà dove nel codice la memoria è stata originariamente attinti.

Mi sono occupato della progettazione di un sistema di rischio di credito una volta (in C ++, anche se questo non è rilevante). Queste cose sono veramente grandi grafici con rischio assegnati ai nodi. Abbiamo avuto una semplice euristica per trovare se fossimo in un ciclo - se abbiamo attraversato più di 500 volte (non ricordo la cifra esatta - era configurabile), la risposta era sì. La maggior parte degli schemi di rilevazione ciclo si basano su euristica come questo.

Ho avuto problemi simili in passato -. Le perdite di memoria a causa di shared_ptr riferimenti ciclici che non è stata individuata per mesi

Attenzione per "cache". Ho un oggetto (chiamiamolo "Factory"), che ha gestito fuori gli oggetti ( "Widget"). Widget aveva la proprietà di essere A) immutabile, e B) ha avuto un shared_ptr<Factory> al suo creatore (a volte creato altri widget, ecc). Tutto ha funzionato bene, fino a quando ho aggiunto una cache Widget di fabbrica - dal momento che i Widget erano immutabili, aveva senso mettere in cache loro, a restituire la stessa ogni volta Widget sono state richieste. La cache è una cache di shared_ptr<Widget>, in modo immediato delle perdite in silenzio. Le correzioni sono evidenti, quindi non andrà in loro.

In definitiva sono stato in grado di appoggiarsi sulla piattaforma che stavo usando per rilevare tali perdite di memoria dalla CRT. CRT di Visual Studio ha una memoria di rilevamento trapelato e il reporting, che ho attivato nel mio programma di test per evitare regressioni:

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 ha probabilmente simile segnalazione di base di perdite, ma non so cosa sia.

Credo che la risposta più semplice è che non c'è solo tanto puntatori intelligenti può fare per voi:

Vi suggerisco di registrazione ogni volta che si make un ciclo, (facile se si creano tutti i tre oggetti in una volta, più complicato altrimenti ...), e quindi controllare il record in cui si eliminano gli oggetti / scollegare, o solo periodicamente, se ciò non è possibile.

Si potrebbe attuare una sorta di interfaccia di debug che restituisce un elenco di shared_ptrs di proprietà di questo oggetto. Avresti bisogno di fare questo per ogni classe memorizzati in uno shared_ptr. Ora avete un grafico generico che si può attraversare, e può utilizzare algoritmi di rilevamento ciclo su di esso. Credo algoritmo componente fortemente connessa di Tarjan potrebbe funzionare per questo, ma la teoria dei grafi non è il mio forte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top