throw und konstruktor
-
Maxi schrieb:
Naja, ich könnt ja schon im catch-block ein delete kl; machen
Das könntest du. Da steht aber immer noch NULL drin. Bis zur Zuweisung kommst du ja gar nicht mehr.
-
camper schrieb:
Der operator delete wird automatisch aufgerufen, falls die Konstruktion des Objektes fehlschlägt. Das ist ist immer eine alles-oder-nichts-Aktion. Du hättest ja auch gar keine Möglichkeit, dort irgendwie selbst aufzuräumen.
Das stimmt afaik nicht ganz...
Es wird zwar nicht delete aufgerufen, was ja einen Destruktor-Aufruf implizieren
würde, aber der Speicher wird freigegeben. Vorsicht, wenn du im Konstruktor
noch etwas mit new anforderst und dann ne Exception schmeißt, dann wird
dieser angeforderte Speicher nicht freigegeben, auch wenn dieser im
Destruktor freigegeben würde.camper schrieb:
Das könntest du. Da steht aber immer noch NULL drin. Bis zur Zuweisung kommst du ja gar nicht mehr.
Ich glaub nicht (bin mir ziemlich sicher), dass da nicht zwangsläufig NULL
drinsteht, aber auf jeden Fall kein Zeiger auf ein gültiges ObjektGruß,
CSpille
-
CSpille schrieb:
camper schrieb:
Der operator delete wird automatisch aufgerufen, falls die Konstruktion des Objektes fehlschlägt. Das ist ist immer eine alles-oder-nichts-Aktion. Du hättest ja auch gar keine Möglichkeit, dort irgendwie selbst aufzuräumen.
Das stimmt afaik nicht ganz...
Es wird zwar nicht delete aufgerufen, was ja einen Destruktor-Aufruf implizieren
würde, aber der Speicher wird freigegeben.Achtung: Es gibt einen kleinen, aber feinen Unterschied zwischen 'operator delete' (reine Speicherfreigabe, kann vom Programmierer bei Bedarf überschrieben werden) und 'delete' (fest vorgegeben - ruft erst den Objekt-Dtor und danach operator delete auf).
camper schrieb:
Das könntest du. Da steht aber immer noch NULL drin. Bis zur Zuweisung kommst du ja gar nicht mehr.
Ich glaub nicht (bin mir ziemlich sicher), dass da nicht zwangsläufig NULL
drinsteht, aber auf jeden Fall kein Zeiger auf ein gültiges ObjektDie Zuweisung zu kl kann erst erfolgen, wenn new sauber zurückgekehrt ist. Das heißt, bei einer Exception wird überhaupt nichts zugewiesen.
(OK, 100% verlassen würde ich mich darauf nicht)
-
CStoll schrieb:
(OK, 100% verlassen würde ich mich darauf nicht)
Wie ist das gemeint? Sollte man sich nicht auf die Richtigkeit deiner Aussage verlassen oder darauf, dass keine Zuweisung stattfindet?
Scott Meyers ist jedenfalls auch der Meinung, dass keine Zuweisung stattfindet und ich verlasse mich auch darauf
Gruss,
DeSoVoDaMu
-
DeSoVoDaMu schrieb:
CStoll schrieb:
(OK, 100% verlassen würde ich mich darauf nicht)
Wie ist das gemeint? Sollte man sich nicht auf die Richtigkeit deiner Aussage verlassen oder darauf, dass keine Zuweisung stattfindet?
Auf meine eigenen Aussagen kann ich mich idR schon verlassen. Aber im obigen Fall war ich mir 'nur' 99% sicher, daß die Zuweisung nicht stattfindet.
-
Hehe, sollte jetzt auch keine Verallgemeinerung im Bezug auf deine Aussagen sein, sondern speziell auf diese eine

-
Wenn die Zuweisung nicht stattfindet und ich rufe delete auf, was passiert dann?
Gut Maxi hat vor dem new den Zeiger bereits mit NULL initialisiert, aber ansonsten würde es beim delete knallen, oder?
Fest steht, dass die nicht nothrow Variante von new eine std::bad_alloc Exception auslöst. Es ist aber nicht im Standard definiert, dass sie NULL zurückgibt!
Also wäre es fatal, wenn ich ein new Aufrufe ohne den Zeiger vorher initialisiert zu haben, oder?
Gruß Paddy
-
Paddy82 schrieb:
Wenn die Zuweisung nicht stattfindet und ich rufe delete auf, was passiert dann?
Gut Maxi hat vor dem new den Zeiger bereits mit NULL initialisiert, aber ansonsten würde es beim delete knallen, oder?
Vermutlich (je nachdem, was dein Compiler mit nicht-initialisierten Variablen macht - das ergibt dann so nette Fehler, die du erst beim Release-Build bemerkst ;))
Fest steht, dass die nicht nothrow Variante von new eine std::bad_alloc Exception auslöst. Es ist aber nicht im Standard definiert, dass sie NULL zurückgibt!
Wenn eine Funktion per throw verlassen wird, kann sie gar nichts zurückgeben. Also ist es sinnlos, darüber nachzudenken, was mit ihren Rückgabewerten passieren könnte. (und afaik besagt die Angabe 'nothrow' nur, daß new keine Exceptions aus sich heraus zurückgeben kann - Exceptions aus dem Ctor werden auch bei der nothrow-Version von new weitergereicht)
-
CStoll schrieb:
Exceptions aus dem Ctor werden auch bei der nothrow-Version von new weitergereicht
Da hast Du recht...
-
CStoll schrieb:
CSpille schrieb:
camper schrieb:
Der operator delete wird automatisch aufgerufen, falls die Konstruktion des Objektes fehlschlägt. Das ist ist immer eine alles-oder-nichts-Aktion. Du hättest ja auch gar keine Möglichkeit, dort irgendwie selbst aufzuräumen.
Das stimmt afaik nicht ganz...
Es wird zwar nicht delete aufgerufen, was ja einen Destruktor-Aufruf implizieren
würde, aber der Speicher wird freigegeben.Achtung: Es gibt einen kleinen, aber feinen Unterschied zwischen 'operator delete' (reine Speicherfreigabe, kann vom Programmierer bei Bedarf überschrieben werden) und 'delete' (fest vorgegeben - ruft erst den Objekt-Dtor und danach operator delete auf).
Zur Ergänzung - Dieses Problem taucht meist nur bei der Diskussion um delete auf, aber das gilt generell:
Wir unterscheiden einerseits zwischen 'operator x' - das ist der eingebaute Operator, der sich so ähnlich wie eine Funktion verhält, oder eine Überladung (wir nennen das ganze einfach so, wie wir code schreiben, so wie void f() eben die Funktion f bezeichnet, so schreiben wir auch x operator+(...) oder void operator delete(...) und das ist dann eben Operator+ bzw. Operator delete. Andererseits gibt es auch noch den + Operator oder den delete Operator. Damit ist das syntaktische Element Operator gemeint: der Bestandteil eines Ausdrucks, der die Art des Ausdrucks bestimmt - also eben das Plus oder das Schlüsselwort delete in einem Ausruck. Für eine präzise Formulierung ist es ist sehr wichtig, auf die Reihenfolge zu achten. Wir kennen das ja zum Beispiel auch von Klassentemplates und Templateklassen.camper schrieb:
Das könntest du. Da steht aber immer noch NULL drin. Bis zur Zuweisung kommst du ja gar nicht mehr.
Ich glaub nicht (bin mir ziemlich sicher), dass da nicht zwangsläufig NULL
drinsteht, aber auf jeden Fall kein Zeiger auf ein gültiges ObjektDie Zuweisung zu kl kann erst erfolgen, wenn new sauber zurückgekehrt ist. Das heißt, bei einer Exception wird überhaupt nichts zugewiesen.
(OK, 100% verlassen würde ich mich darauf nicht)Mein Statement bezog sich auf den Code, so wie er konkret gegeben war. Keine Zuweisung heißt in diesem Falle, es passiert überhaupt nichts mit dem Zeiger. Das ist dann auch keine Frage von Operator- vs. Funktionssemantik. Um zuweisen zu können, muss erst einmal ein Wert bestimmt werden und das schlägt ja fehl. Wenn ich sage, dort steht NULL drin, dann nur, weil das auch vorher schon so war.