Delete c++
-
Hallo
Ich habe 2 classen
class a { ~a() { for (int i = 0; i < m_protocols.size(); i++ ) { xwProtocol* p = m_protocols.at(i); if ( p ) { delete p; p = 0; } } } } class b { ~b() { for (int i = 0; i < m_protocols.size(); i++ ) { xwProtocol* p = m_protocols.at(i); if ( p ) { delete p; p = 0; } } } }Wenn ich nun folgendes mache :
....
Protocol* p = new Protocol();
a->add(p);
b->add(p);
delete a;
delete b; hier gibts einen crash weil p in a schon gelöscht wurde!
wie kann ich aber bein delete überprüfen ob das objekt wo er pointer hinzeigt noch existiert?Thx
-
Kurze Antwort:
Gar nicht!volkard sagt immer:
Zu jeden new gehört genau ein delete
und da gebe ich im absolut recht.
Ansonsten kannst du einen Container mit Smart-Pointern verwenden,
falls du keine Objekt-Zugehörigkeit definieren kannst, nach
der sich dein delete richtet.Warum das bei dir 2 verschiedene Klassen sind, frag ich mal nicht

-
-
Ich gebe XSpille recht. Die Verantwortung liegt definitiv bei der Klasse (oder Funktion), welche p erzeugt und soll daher den Speicher dafür auch wieder freigeben.
Ansonsten gäbe es die Möglichkeit da einen Smart Pointer zu benutzen, welcher dann auch schaut, ob der Zeiger bereits fregegeben worden ist. Aber das ist nur etwas für einen Spezialfall. Im generellen funktioniert das wirklich so, dass der, der das Objekt erzeugt auch wieder zerstört.
-
Nur nicht Smart-Pointer verwenden, wenn man Pointer-Container (z.B. die von Boost) braucht.

-
saschaappel schrieb:
if ( p ) { delete p; p = 0; }Noch ein Tipp: statt diesem ganzen Rotz kannst du einfach nur
delete p;schreiben, das macht das gleiche. Der Rest ist unnötig.
-
Hi vielen dank
smart_pointers bei std::vector sollte man glaube ich nicht verwenden.
Ok vielen dank, habt mir geholfen, ich weiss das das der falsche weg ist!Gruss
-
saschaappel schrieb:
smart_pointers bei std::vector sollte man glaube ich nicht verwenden.
auto_ptrgeht nicht mit STL-Containern,shared_ptrschon. Aber der ist für geteilte Besitzverhältnisse. Für besitzende Zeiger in Containern ohne Shared-Semantik gibts wie schon genannt spezialisierte Lösungen (Boost.PointerContainer).
-
Nukularfüsiker schrieb:
saschaappel schrieb:
if ( p ) { delete p; p = 0; }Noch ein Tipp: statt diesem ganzen Rotz kannst du einfach nur
delete p;schreiben, das macht das gleiche. Der Rest ist unnötig.Das stimm ja nicht ganz...
Der Zeiger wird ja in deinem angesprochenen Fall nicht auf 0 gesetzt.
Das braucht man zwar in den seltensten Fällen, aber sollte nicht
verschwiegen werden.
Wenn man z.B. das letzte Element einer Liste löschen will,
würde das einen großen Unterschied machen
Das wäre identisch:
delete p; p = 0;In deinem Fall reicht aber:
delete p;delete p überprüft vorher, ob p==0 ist
Das meinte Nukularfüsiker sehr wahrscheinlich
-
XSpille schrieb:
Nukularfüsiker schrieb:
saschaappel schrieb:
if ( p ) { delete p; p = 0; }Noch ein Tipp: statt diesem ganzen Rotz kannst du einfach nur
delete p;schreiben, das macht das gleiche. Der Rest ist unnötig.Das stimm ja nicht ganz...
Aber in
{ xwProtocol* p = m_protocols.at(i); if ( p ) { delete p; p = 0; } }ist es identisch zu
{ xwProtocol* p = m_protocols.at(i); delete p; }denn p fliegt ja sofort weg.
-
Gebe ich dir absolut recht...
Die Aussage von Nukularfüsiker konnte man (denke ich) auch als allgemeine
Aussage interpretieren.Ich wollte nur Missverständnisse vermeiden

-
XSpille schrieb:
Die Aussage von Nukularfüsiker konnte man (denke ich) auch als allgemeine
Aussage interpretieren.Jo, die allgemeine Aussage ist, dass man vor delete nicht auf 0 prüft und man unbenutzte lokale Pointer nicht auf 0 setzen braucht.
-
Nukularfüsiker schrieb:
XSpille schrieb:
Die Aussage von Nukularfüsiker konnte man (denke ich) auch als allgemeine
Aussage interpretieren.Jo, die allgemeine Aussage ist, dass man vor delete nicht auf 0 prüft und man unbenutzte lokale Pointer nicht auf 0 setzen braucht.
Und man braucht im Destruktor seine Memberpointers nicht auf 0 zu setzen. Das wird mir nämlich auch oft angetan.