std::list<Node *> lst;
//....
Node * node = /* get from somewhere pointer on my node */;
lst.remove(node);
Nicht std::list::remove-Methode Aufruf Destruktor(und freier Speicher) jedes entfernte element? Wenn ja, wie kann ich es vermeiden?
InformationsquelleAutor der Frage Siarhei Fedartsou | 2010-11-23
Ja, das entfernen eines
Foo*
aus einem container zerstört dieFoo*
aber es wird nicht lassen Sie dieFoo
. Zerstören ein raw-pointer ist immer ein no-op. Es gibt keinen anderen Weg! Lassen Sie mich Ihnen einige Gründe, warum.Storage class
Löschen ein Zeiger macht nur Sinn, wenn der pointee war eigentlich dynamisch zugewiesen, aber wie könnte die Laufzeit vielleicht wissen, ob das der Fall ist, wenn die Zeiger-variable zerstört wird? Zeiger können auch auf statische und automatische Variablen und das löschen einer von denen die Renditen Undefiniertes Verhalten.
Baumelnden Zeiger
Gibt es keine Möglichkeit, herauszufinden, ob der pointee hat bereits veröffentlicht worden in der Vergangenheit. Löschen Sie die gleichen Zeiger zweimal Erträge Undefiniertes Verhalten. (Es wird ein baumelnden Zeiger nach dem ersten löschen.)
Nicht initialisierte Zeiger
Ist es auch unmöglich zu erkennen, ob eine pointer-variable initialisiert wurde überhaupt. Ratet mal, was passiert, wenn Sie versuchen, zu löschen, wie ein pointer? Noch einmal, die Antwort ist Undefiniertes Verhalten.
Dynamische arrays
Den Typ system unterscheidet nicht zwischen einem Zeiger auf ein einzelnes Objekt (
Foo*
) und einen Zeiger auf das erste element eines Arrays von Objekten (auchFoo*
). Wenn ein Zeiger-variable zerstört wird, die Laufzeit nicht möglich, herauszufinden, ob die Freigabe der pointee überdelete
oder überdelete[]
. Die Freigabe über das falsche Formular aufruft Undefiniertes Verhalten.Zusammenfassung
Da die Laufzeit nicht etwas vernünftiges mit der pointee, die Zerstörung einer Zeiger-variable ist immer ein no-op. Nichts tun ist auf jeden Fall besser als verursacht Undefiniertes Verhalten durch eine uninformierte raten 🙂
Beratung
Statt roher Zeiger, betrachten Sie die Verwendung von smart-Pointer als Wert geben Sie Ihre container, weil Sie die Verantwortung für die Freigabe der pointee, wenn es nicht mehr benötigt wird. Je nach Ihrem Bedarf, verwenden Sie
std::shared_ptr<Foo>
oderstd::unique_ptr<Foo>
. Wenn Ihr compiler unterstützt C++0x noch, verwenden Sieboost::shared_ptr<Foo>
.NieIch wiederhole, NIE verwenden
std::auto_ptr<Foo>
als Wert geben Sie in einem container.InformationsquelleAutor der Antwort fredoverflow
Ruft er den Destruktor jedes der Elemente in der
list
- aber das ist nicht einNode
Objekt. Seine eineNode*
.So ist es nicht löschen Sie die
Node
Zeiger.Macht das Sinn?
InformationsquelleAutor der Antwort John Dibling
Es tut, rufen Sie den Destruktor der Daten in der Liste. Das bedeutet,
std::list<T>::remove
ruft den DestruktorT
(was notwendig ist, wennT
ist so etwas wiestd::vector
).In Ihrem Fall, es ruft den Destruktor
Node*
das ist ein no-op. Es doesn ' T rufen Sie den Destruktornode
.InformationsquelleAutor der Antwort jpalecek
Ja, obwohl in diesem Fall Knoten* hat keinen Destruktor. Je nach Interna obwohl die verschiedenen Knoten* Werte werden entweder gelöscht oder zerstört durch die scoping-Regeln. Wenn Knoten*, wo einige nicht-fundamentalen Typ, ein Destruktor aufgerufen werden würde.
Wird der Destruktor aufgerufen, der Knoten? Nein, aber 'Knoten' ist nicht der element-Typ in der Liste.
Als zu Ihrer anderen Frage, kann man nicht. Die standard-Liste-container (in der Tat ALLE standard-Container) übernehmen Verantwortung für Ihre Inhalte und reinigen Sie es bis. Wenn Sie nicht möchten, dass dies geschehen kann, muss die standard-Container sind nicht eine gute Wahl.
InformationsquelleAutor der Antwort Crazy Eddie
Da sind Sie setzen Zeiger in eine
std::list
Destruktoren werden nicht aufgerufen, auf dem Spitzen-zuNode
Objekte.Wenn Sie speichern möchten, heap zugewiesenen Objekte in STL-Containern haben und Sie werden zerstört beim entfernen, wickeln Sie Sie in ein smart-pointer wie
boost::shared_ptr
InformationsquelleAutor der Antwort wkl
Der beste Weg zu verstehen ist, um zu testen, jedes Formular, und beobachten Sie die Ergebnisse. Gekonnt verwenden Sie die container-Objekte mit eigenen, benutzerdefinierten Objekten müssen Sie ein gutes Verständnis für das Verhalten.
Kurz gesagt, für die Art
Node*
weder der deconstructor heißt noch löschen/free wird aufgerufen, allerdings für die ArtNode
den deconstructor würde aufgerufen werden, während die Berücksichtigung löschen/free ist eine Implementierung detail-Liste. Bedeutung, es hängt davon ab, ob die Liste der Implementierung verwendet new/malloc.Im Falle einer
unique_ptr<Node>
der deconstructor wird aufgerufen und der Aufruf von delete/free passieren wird, da Sie hatte, um ihm etwas zugeteiltnew
.Achten Sie auf die Speicher-Adressen. Man kann sagen, die zeigen in den stack und die zeigen in den heap durch die Bereiche.
InformationsquelleAutor der Antwort kmcguire