2010-08-04 1 views
7

Unter Linux habe ich etwas generierten C++ - Code aus einer statischen Bibliothek, die eine globale Variable definiert. Eine einzelne Instanz dieser globalen Variablen wird von zwei gemeinsam genutzten Bibliotheken gemeinsam genutzt, die sich auf ihr Symbol beziehen.Unter Linux, warum wird der Destruktor zweimal auf gemeinsam genutzte Instanz der globalen Variablen in C++ ausgeführt?

Wenn der Prozess heruntergefahren und die statische Beendigungsphase ausgeführt wird, sehe ich, dass der Destruktor auf dieser freigegebenen Instanz zweimal ausgeführt wird! Vermutlich einmal pro Bibliothek als jeder entlädt.

Diese Frage steht in engem Zusammenhang mit einer anderen, die ich kürzlich hier gesehen habe: related question. Das klingt nach dem gleichen Verhalten, aber es gibt keine Diskussion darüber, warum es passiert.

Kennt jemand die theoretische Erklärung hinter diesem Verhalten?

+0

Es sollte nur einmal pro Variable durch den Compiler generierten Code ausgeführt werden. Versuchen Sie, die Adresse der Variablen zu ermitteln, während der Destruktor ausgeführt wird, um sicherzustellen, dass es sich um dasselbe Objekt handelt. –

+0

Vielleicht haben Sie in einer Smart-Pointer-Klasse einen Zeiger auf das Objekt gespeichert, der versucht, seinen targer zu zerstören. –

+0

Also ist das Globale in (einer Kompilierungseinheit von) nur eine der Bibliotheken definiert? – Thomas

Antwort

2

Wenn Sie einen nackten Zeiger nehmen und ihn zweimal in einen Smart Pointer setzen, wird er zweimal zerstört, einmal für jeden Container Refcount, der auf Null fällt.

Also, wenn Sie den nackten Zeiger in beide Bibliotheken übergeben, würde das tun. Jeder legt es in ein gemeinsames Zeigerobjekt und jeder von diesen macht die Zerstörung. Wenn Sie den Stack-Backtrace während des dtors sehen können, sollte dies in beiden Bibliotheken angezeigt werden.

+1

Mit jedem regulären Debugger sollte es einfach sein, die Call-Stack-Backtrace zu überprüfen und herauszufinden, wer diesen Destruktor aufruft. – Vargas

0

C++ hat eine Regel, die "One Definition Rule" genannt:

Jedes Programm wird genau eine Definition jeder Nicht-Inline-Funktion oder ein Objekt enthalten, die in diesem Programm verwendet wird; keine Diagnose erforderlich. Die Definition kann explizit im Programm erscheinen, sie kann im Standard oder in einer benutzerdefinierten Bibliothek gefunden werden, oder (falls zutreffend) implizit definiert (siehe 12.1, 12.4 und 12.8).

Wikipedia hat eine article, die das genauer erklärt.

Sie haben in Ihrer Frage keinen Code angegeben, daher kann ich mir in Ihrem Fall nicht sicher sein, aber in the question you linked to bestand das Beispiel in der Frage darin, dieselbe Variable in zwei gemeinsam genutzten Bibliotheken zu definieren. Dies verletzte die "One Definition Rule", von der offensichtlich die Finalisierungsstrategie des dynamischen Linkers abhängt, wodurch der Destruktor zweimal aufgerufen wird.

Verwandte Themen