Frage

Dies ist nur für Neugier willen, weil ich nicht new und delete in C ++ mit Ausnahme der einfachsten Anwendungen verwendet haben.

Ich weiß, dass delete Mitteilungen Speicher. Das, was ich frage mich, ist wie funktioniert es komplexere Fälle behandeln?

Zum Beispiel, wenn ich eine benutzerdefinierte Klasse wie folgt aus:

class MyClass
{
public:
    MyClass();
    ~MyClass()
    {
        delete [] intArray;
    }
    //public members here
private:
    int* intArray;
};

Unter der Annahme der Klasse zuordnet Speicher irgendwie für intArray, und es dann in den destructor loslassen, Was passiert, wenn ich die Klasse wie folgt verwendet: MyClass* myClass = new MyClass(); und es später wieder freigelassen mit delete myclass;

Wie delete die Freigabe aller Speicher umgehen? Hat der Klassendestruktor erste der gesamte Speicher von der Klasse zugewiesen freizugeben aufgerufen (dh int* intArray) und dann die Speicher zugewiesen, die Klasse zu halten?

Was passiert, wenn ich hatte eine Klasse wie folgt:

class MyClass
{
public:
    MyClass();
    ~MyClass()
    {
        delete anotherMyClass;
    }
    //public members here
private:
    MyClass* anotherMyClass;
};

anotherMyClass Unter der Annahme, nicht mit dem Konstruktor zugeordnet, die Speicher sehr schnell aufbrauchen würde, was, wenn es eine Kette von MyClasses war miteinander verbunden wie eine verknüpfte Liste? Würde die Delete-Anweisung in der destructor Arbeit in diesem Fall? Würde jeder anotherMyClass rekursiv gelöst werden, wenn der Destruktor aufgerufen wird?

Gibt es spezifische seltsame Tricks oder Einsprüche mit den new und delete Anweisungen, die Sie kennen?

War es hilfreich?

Lösung

ein Zeiger (p) ein dynamisch zugewiesenen Objekt gegeben, delete macht zwei Dinge:

  1. Sie ruft den destructor des dynamisch zugewiesenen Objekts. Beachten Sie, dass, wenn ~MyClass() abgeschlossen ist, werden die Destruktoren für alle Membervariablen der Klasse-Typ bezeichnet.
  2. Es gibt den Speicher durch das dynamisch zugewiesenen Objekt besetzt.

Es sucht nicht die Elementvariablen des Objekts für andere Zeiger frei; es macht keinen anderen Speicher frei und tut nichts anderes.

Wenn Sie die Speicher von intArray darauf befreien müssen, müssen Sie es in dem destructor von delete MyClass.

Doch in fast allen C ++ Code, haben Sie Sorge über diese nicht benötigen. Sie sollten automatisch verwalten dynamisch zugewiesenen Objekte mit Smart-Pointer wie shared_ptr, unique_ptr, auto_ptr und scoped_ptr sein. Manuelles Ressourcenmanagement ist bestenfalls schwierig und soll nach Möglichkeit vermieden werden.

Dies ist Teil einer breiteren Idiom ist, Scope-Bound Resource Management (SBRM, auch Ressourcen Acquisition genannt ist Initialisierung oder RAH). Dies ist bei weitem die wichtigste Design-Muster zu verstehen und überall in Ihrem C ++ Code zu verwenden.

Wenn in der Klasse Sie diese stattdessen erklärt hatte:

boost::scoped_ptr<int> intArray;

dann, wenn das scoped_ptr<int> Objekt zerstört wird, wird es den Zeiger freizugeben, dass es hält. Sie müssen dann keine Arbeit nicht tun, um das Objekt manuell zu zerstören.

In gut geschriebenen, modernen C ++ Code, sollten Sie nur selten manuell Verwendung delete müssen. Smart-Pointer und andere SBRM Behälter sollen jede Art von Ressource zu verwalten verwendet werden, die Bereinigung benötigt, einschließlich dynamisch zugewiesenen Objekte.


In Ihrem zweiten Beispiel gegeben eine verkettete Liste, das aussieht wie:

x -> y -> z -> 0

würden Sie eine Reihenfolge der Operationen haben das wie folgt aussieht:

delete x;
  x.~MyClass();
    delete y;
      y.~MyClass();
        delete z;
          z.~MyClass();
            delete 0;
          [free memory occupied by z]
      [free memory occupied by y]
  [free memory occupied by x]

Die Objekte in der verknüpften Liste würden in umgekehrter Reihenfolge zerstört werden.

Andere Tipps

delete intArray;

gehe ich davon aus intArray zeigt auf das erste Element eines int Array? In diesem Fall ergibt delete intArray nicht definiertes Verhalten. Wenn Sie zuteilen über new[], Sie muss Freigabe über delete[].

delete[] intArray;

Ja, ich weiß, delete intArray Macht erscheinen zu gut funktionieren auf bestimmten Systemen mit bestimmten Compiler Versionen unter bestimmten Compiler-Optionen - oder auch nicht. Das ist undefiniertes Verhalten für ya.

Außerdem sollten Sie die Rule of Three folgen. Ihren eigenen destructor definieren, sondern auf dem implizit definierten Copykonstruktor und kopiert Zuweisungsoperator unter Berufung ist ein Rezept für eine Katastrophe.

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