2010-08-04 20 views
7

Su Linux, ho generato un codice C++ generato da una libreria statica che definisce una variabile globale. Una singola istanza di questa variabile globale è condivisa tra due librerie condivise che si riferiscono al suo simbolo.Su Linux, perché il distruttore viene eseguito due volte sull'istanza condivisa della variabile globale in C++?

Quando il processo si arresta e viene eseguita la fase di terminazione statica, vedo che il distruttore su questa istanza condivisa viene eseguito due volte! Presumibilmente una volta per libreria mentre ognuno scarica.

Questa domanda è strettamente correlata a un'altra che ho visto di recente qui: related question. Sembra lo stesso comportamento, ma non c'è discussione sul perché sta accadendo.

Qualcuno conosce la spiegazione teorica di questo comportamento?

+0

Dovrebbe essere eseguito una volta sola per variabile dal codice generato dal compilatore. Prova a ottenere l'indirizzo della variabile mentre viene eseguito il distruttore per verificare che si tratti dello stesso oggetto. –

+0

Forse hai memorizzato un puntatore sull'oggetto in una classe di puntatore intelligente, che tenta di distruggere il suo mirino. –

+0

Quindi il globale è definito in (una unità di compilazione di) solo una delle librerie? – Thomas

risposta

2

Se si prende un puntatore nudo e lo si posiziona in un puntatore intelligente (due volte), verrà distrutto due volte, una volta per ogni contatore di contenitori che scende a zero.

Quindi, se si passa il puntatore nudo in entrambe le librerie, ciò lo farebbe. Ognuno lo colloca in un oggetto puntatore condiviso e ognuno di questi esegue la distruzione. Se riesci a vedere lo stack backtrace durante il dtor, dovrebbe mostrare che sta accadendo in entrambe le librerie.

+1

Utilizzando un normale debugger, dovrebbe essere facile controllare lo stack di chiamata backtrace e scoprire chi sta chiamando questo distruttore. – Vargas

0

C++ ha una regola chiamata "Una regola Definizione":

Ogni programma deve contenere esattamente un definizione di ogni funzione non inline o un oggetto che viene usata in quel programma; nessuna diagnostica richiesta. La definizione può apparire esplicitamente nel programma, può essere trovata nello standard o in una libreria definita dall'utente o (quando appropriato) è definita implicitamente (vedere 12.1, 12.4 e 12.8).

Wikipedia ha uno article che spiega questo in modo più dettagliato.

Non hai inserito il codice nella tua domanda, quindi non posso essere sicuro del tuo caso, ma in the question you linked to, l'esempio nella domanda stava definendo la stessa variabile in due librerie condivise. Ciò ha violato la "One Definition Rule", che apparentemente dipende dalla strategia di finalizzazione del linker dinamico, provocando il doppio intervento del distruttore.

Problemi correlati