17 Stimmen

C++ mischt neu/löschen zwischen Libs?

Wenn ich die new Schlüsselwort in meiner Bibliothek (die anders aufgebaut ist als meine Hauptanwendung), wenn ich es in meiner Hauptanwendung mit delete Besteht die Möglichkeit, dass ich einen Absturz/Fehler erhalte?

22voto

Roger Lipscombe Punkte 84868

Das kommt darauf an. Wenn es sich um eine statische Bibliothek handelt, ist wahrscheinlich alles in Ordnung - der Code wird im gleichen Kontext wie das Hauptprogramm ausgeführt und verwendet die gleiche C++-Laufzeitbibliothek. Das bedeutet, dass new y delete verwenden denselben Heap.

Wenn es sich um eine gemeinsam genutzte Bibliothek (eine DLL) handelt, dann ist das wahrscheinlich nicht in Ordnung. Der in der DLL laufende Code könnte eine andere C++-Laufzeitbibliothek verwenden, was bedeutet, dass das Layout des Heaps anders ist. Möglicherweise verwendet die DLL einen ganz anderen Heap.

Aufruf von delete (im Hauptprogramm) auf einen von der DLL zugewiesenen Zeiger (oder umgekehrt) führt (im besten Fall) zu einem sofortigen Absturz oder (im schlimmsten Fall) zu einer Speicherbeschädigung, deren Aufspüren eine Weile dauern wird.

Sie haben mehrere Möglichkeiten. Die erste ist die Verwendung des Musters "Fabrikmethode" zum Erstellen und Löschen dieser Objekte:

Foo *CreateFoo();
void DeleteFoo(Foo *p);

Diese sollten no in der Header-Datei implementiert werden.

Alternativ können Sie auch eine Destroy Methode auf das Objekt:

class Foo
{
    ~Foo();

public:
    virtual void Destroy();
};

...wieder, implementieren Sie dies nicht in der Header-Datei. Sie würden es so implementieren:

void Foo::Destroy()
{
    delete this;
    // don't do anything that accesses this object past this point.
}

Beachten Sie, dass der Destruktor für Foo privat ist, so dass Sie den Foo::Destroy .

Microsoft COM macht etwas Ähnliches, indem es eine Release Methode, die das Objekt löscht, wenn seine Referenzanzahl auf Null sinkt.

11voto

Jesse Pepper Punkte 3225

Ja, in der Tat. Insbesondere sehen Sie Probleme mit Debug/Release-Heaps, die unterschiedlich sind, auch wenn Ihre Bibliothek die neue Platzierung oder einen benutzerdefinierten Heap verwendet, werden Sie ein Problem haben. Das Debug/Release-Problem ist jedoch bei weitem das häufigste.

6voto

Charles Anderson Punkte 17827

Ja, das werden Sie. Eine einfache Lösung besteht darin, in Ihrer Bibliothek Funktionen zum Erstellen und Löschen bereitzustellen, die von der Hauptanwendung aus aufgerufen werden können. Die Create-Funktion führt die Neuanlage durch und gibt einen Zeiger zurück, der später zum Löschen an die Delete-Funktion übergeben wird.

5voto

Zan Lynx Punkte 51045

Dieses Problem habe ich bisher nur unter Windows gesehen.

In Unix-Systemen ist es nicht üblich, gemeinsam genutzte Bibliotheken zu zwingen, sich innerhalb eines Programms mit verschiedenen Versionen derselben Bibliothek zu verbinden, und alle geladenen Symbole sind global sichtbar. Das bedeutet, dass, wenn ein Objekt in einem Teil des Codes zugewiesen und in einem anderen gelöscht wird, beide dieselbe Systembibliothek dafür verwenden.

Ich muss sagen, dass dieses Problem, das Windows mit seinen verschiedenen C-Laufzeit-DLLs verursacht, wirklich ärgerlich und unnatürlich für einen C-Programmierer ist. Schauen Sie sich die C-Bibliothek an; sie hat Funktionen wie strdup, die die Zeichenkette malloc und erwarten, dass der Programmierer free() dafür aufruft. Aber machen Sie das Gleiche in Ihrer eigenen Bibliothek unter Windows und warten Sie einfach auf die Explosion. Sie werden auch warten müssen, denn es wird nicht während der Entwicklung passieren, sondern erst, nachdem Sie die kompilierte DLL an einen anderen armen Trottel weitergegeben haben.

3voto

Max Lybbert Punkte 19181

Alte neue Sache hat bereits darüber berichtet. Er gibt auch eine Liste der wichtigsten Lösungen von Microsoft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X