Frage

Wenn ich das new Stichwort in meiner Bibliothek verwenden (die als meine Hauptanwendung anders gebaut ist), wenn ich es in meinem Haupt-App mit delete löschen, gibt es eine Chance, dass ich einen Crash / Fehler bekommen kann?

War es hilfreich?

Lösung

ja indeedy. Insbesondere sehen Sie Probleme mit Debug / Release Haufen anders zu sein, auch wenn die Bibliothek Platzierung neu verwendet oder jede benutzerdefinierte Heap werden Sie ein Problem haben. Das Debug / Release Problem ist bei weitem der häufigste though.

Andere Tipps

Es hängt davon ab. Wenn Sie über eine statische Bibliothek sprechen, dann werden Sie wahrscheinlich in Ordnung sein - der Code im gleichen Kontext wie das Hauptprogramm ausgeführt wird, die gleiche C ++ Laufzeitbibliothek verwenden. Das bedeutet, dass new und delete den gleichen Heap verwenden.

Wenn Sie über eine gemeinsam genutzte Bibliothek (DLL) im Gespräch, dann werden Sie wahrscheinlich nicht in Ordnung sein. Der Code in der DLL ausgeführt werden möglicherweise eine andere C ++ Laufzeitbibliothek verwenden, was bedeutet, dass das Layout des Haufens wird anders sein. Die DLL kann insgesamt einen anderen Haufen werden.

delete Calling (im Hauptprogramm) auf einem Zeiger von der DLL (oder umgekehrt) zugeordnet wird führen zu (bestenfalls) ein sofortiger Absturz oder (im schlimmsten Fall) Speicherfehler, die eine Weile auf der Spur nehmen würden.

Sie haben ein paar Optionen. Die erste ist die „Factory-Methode“ Muster zu verwenden, um diese Objekte zu erstellen und löschen:

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

Diese sollten nicht in der Header-Datei implementiert werden.

Alternativ können Sie auch eine Destroy Methode für das Objekt definieren:

class Foo
{
    ~Foo();

public:
    virtual void Destroy();
};

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

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 Foo::Destroy nennen haben.

Microsoft COM macht etwas ähnliches, wo es eine Release Methode definiert, die das Objekt löscht, wenn der Referenzzähler auf Null sinkt.

Ja, Sie werden. Eine einfache Lösung ist Erstellen und Löschen von Funktionen in Ihrer Bibliothek zu schaffen, die von der Hauptanwendung aufgerufen werden kann. Die Create-Funktion wird die neue durchführt und einen Zeiger zurückgeben, die später in die Löschfunktion zum Löschen übergeben wird.

Es ist ein Problem, dass ich nur auf Windows gesehen habe.

Die Unixish Systeme machen keine Gewohnheit gemeinsam genutzte Bibliotheken zwingen zu verschiedenen Versionen derselben Bibliothek im gleichen Programm zu verknüpfen und alle geladenen Symbole sind global sichtbar. Das bedeutet, dass, wenn ein Objekt in einem Teil des Codes und gelöscht in einem anderen zugewiesen wird, werden beide die gleiche Systembibliothek verwenden, es zu tun.

ich zu sagen habe, ist dieses Problem von Windows mit seinem verschiedenen C Runtime-DLLs erstellt ist wirklich ärgerlich und unnatürlich zu einem C-Programmierer. Sehen Sie in der C-Bibliothek; es hat Funktionen wie strdup, die die Zeichenfolge malloc und erwarten, dass auf sie der Programmierer nennen free (). Aber das gleiche tun in Ihrer eigenen Bibliothek auf Windows und nur für die Explosion warten. Sie werden auch warten müssen, weil es nicht während der Entwicklung geschehen wird, aber erst, nachdem Sie die kompilierte DLL zu einem anderen armen Saft gegeben haben.

Old New Thing hat diese bedeckt vor . Er gibt auch eine Liste von Microsofts Haupt-Lösungen.

Sie ganz richtig sind, dass es ein Problem gibt, aber für die meisten Fälle ist es eine noch einfachere Lösung als die anderen Antworten (bisher) vorgeschlagen. Sie können mit neuen fortsetzen und löschen frei -. Alles, was Sie tun müssen, ist neu überlasten und für jede Klasse in Ihrer Bibliothek löschen, die über DLL Grenzen hinweg genutzt werden könnten

Ich persönlich definierte nur eine einfache Klasse, um die benötigte Funktionalität zu bieten:

class NewDelete
{
    public:
        void *operator new (size_t size);
        void operator delete (void *memory);
        void *operator new (size_t size, void *ptr);
        void operator delete (void *memory, void *ptr);
};

Solange diese vier Mitgliedsfunktionen alle in der gleichen DLL definiert sind, dann ist jede Klasse, die von dieser Klasse abgeleitet ist automatisch „DLL-safe“ - neu und löschen können in der Regel ohne sich Gedanken über DLL Grenzen, die auf ihnen verwendet werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top