2010-08-22 3 views
29

Ho una piuttosto complessa applicazione multi-threaded (server) che di volta in volta andrà in crash a causa di un'asserzione:shared_ptr asserzione px = 0 fallito

/usr/include/boost/smart_ptr/shared_ptr.hpp:418: T* boost::shared_ptr< <template-parameter-1-1> >::operator->() const [with T = msg::Player]: Assertion `px != 0' failed. 

sono stato in grado di individuare la causa ed è stato chiedendo se questo è un problema con boost :: shared_ptr o sono io?

Ho provato g ++ 4.4.3-4ubuntu5 e llvm-g ++ (GCC) 4.2.1 con ottimizzazione e senza ottimizzazione e libboost1.40-dev (= 1.40.0-4ubuntu4).

+1

bug multithreading sono difficili da individuare. Dato che sei su Linux, non c'è motivo di non usare valgrind - ti aiuterà molto a trovare il bug. – nos

+0

Sto usando valgrind estesamente e ottengo zero errori (con memcheck) fino a quando non si verifica l'asserzione. Sto ancora imparando come interpretare i messaggi di errore drd come la maggior parte di loro (carico di conflitto/archivio su tipi booleano/intero) non sembrano un problema. – Horacio

risposta

33

Non ci dovrebbero essere problemi con l'utilizzo di boost::shared_ptr se si inizializzano correttamente i puntatori condivisi e si utilizza lo stesso contesto di gestione della memoria per tutte le librerie di oggetti condivise.

Nel tuo caso stai tentando di utilizzare un puntatore condiviso non inizializzato.

boost::shared_ptr<Obj> obj; 
obj->Something(); // assertion failed 

boost::shared_ptr<Obj> obj(new Obj); 
obj->Something(); // ok 

Vorrei consigliare di inizializzarli sulla dichiarazione, quando possibile. La gestione delle eccezioni può creare molti percorsi "invisibili" per l'esecuzione del codice e potrebbe essere piuttosto difficile identificare i puntatori condivisi non inizializzati.

PS: Ci sono altri problemi se si caricano/scaricano moduli in cui sono in uso shared_ptr che portano al caos. Questo è molto difficile da risolvere ma in questo caso avresti un puntatore diverso da zero. Questo non è quello che ti sta succedendo in questo momento.

3

si potrebbe desiderare di fare in modo che si

di utilizzare sempre una variabile di puntatore intelligente chiamato a tenere il risultato della nuova

come si raccomanda qui: boost::shared_ptr - Best Practices

Saluti, Jonny