Hier ist das Szenario:
- libA.so und libB.so sind beide statisch mit derselben STL verknüpft.
- libA.so verfügt über eine öffentliche API, die einen std :: string zurückgibt.
- libB.so ruft diese Funktion auf und erhält eine Kopie der Zeichenfolge.
- Wenn die Kopie der Zeichenfolge von libB.so den Gültigkeitsbereich verlässt, wird der Destruktor der Zeichenfolge aufgerufen.
- Die Anwendung seg Fehler beim Versuch, die kopierte Zeichenfolge freizugeben.
Ich habe an anderer Stelle gelesen, dass eine solche statische Verknüpfung schlecht ist, aber ich möchte besser verstehen, warum sie schlecht ist. Kann jemand erklären, warum die obige Sequenz abstürzen würde?
c++
libraries
stl
static-linking
user1509041
quelle
quelle
Antworten:
Lassen Sie uns sehr sorgfältig darüber nachdenken. libA.so ist statisch mit der STL verknüpft. Die STL existiert jedoch nicht isoliert, sondern erfordert die C-Laufzeit (CRT). Beide befinden sich in der statischen Bibliothek libstdc ++. Dies bedeutet, dass libA.so und libB.so separate CRT-Datenstrukturen haben. Insbesondere unterscheidet sich der von libA.so verwendete Heap von dem von libB.so verwendeten Heap. Das Zuweisen einer Zeichenfolge aus dem Laufzeitheap von libA und der Versuch, die Laufzeit von libB freizugeben, funktionieren einfach nicht, da die Laufzeit von libB keine Datensätze zum Zuweisen der Zeichenfolge enthält. Die einzige Möglichkeit, die Zeichenfolge korrekt zu zerstören, besteht darin, den Destruktor in libA.so aufzurufen.
Man könnte fragen: aber libB.so erhält eine Kopie der Zeichenfolge, oder? Ja, das stimmt, aber wer hat diese Kopie zugewiesen? Es wurde mithilfe des Kopierkonstruktors im Kontext der Laufzeit der libA zugewiesen.
Sie können jedoch weiterhin die Zeichenfolge von libB.so verwenden. Von dort aus kann man es einfach nicht zerstören.
Sie können libB auch einen Zeiger auf die Zeichenfolge empfangen lassen und anschließend im Kontext der Laufzeit der libB eine Kopie davon erstellen. Diese Kopie kann von libB zerstört werden.
Und deshalb ist statische Verknüpfung manchmal schlecht.
quelle
std::string
das Problem einfach nicht: EntwederlibB.so
empfängt es eine Kopie der Zeichenfolge, wobei der Speicher in seinem eigenen Speicher verwaltet wird, oder es erhält eine Referenz / einen Zeiger auf die Zeichenfolge inlibA.so
und versucht nicht, sie zu entfernen die Zeichenfolge aus dem eigenen Speicher.Die STL ist so genannt "state-full" (im Gegensatz zu "state-less"), was bedeutet, dass sie einige statische Elemente enthält. Wenn Sie STL statisch mit libA.so und libB.so verknüpfen, erhalten Sie zur Laufzeit zwei Instanzen der STL-Bibliothek im Speicher (mit zwei Kopien statischen Materials). Jede dieser beiden Kopien verwaltet die zugewiesenen Ressourcen unabhängig voneinander, und die in einer Bibliotheksinstanz zugewiesenen Ressourcen können in einer anderen nicht freigegeben werden
quelle