C++ Lokale Objekte zerstören, die nicht im Heap stehen

Tockra

Lt. Commander
Registriert
Dez. 2008
Beiträge
1.058
Hey Leute,

ich habe jetzt nicht wirklich was dazu bei google gefunden, mich würde aber interessieren, ob in folgendem Beispiel, die erste Instanz der Klasse zerstört wurde und der Destruktor von ihr aufgerufen wurde!?

Code:
void irgendeineMethode() {
      AudioInput a(...);
      ...
      a = null;
      // ist a jetzt zerstört?
      a = AudioInput(...); // neues a ?
}


Gruß
T
 
Nein, ist sie nicht. Du weist in Zeile 4 lediglich dem Objekt a über den Zuweisungsoperator den Wert null zu. Ob das überhaupt kompilierbar ist, hängt davon ab, welchen Typs null eigentlich ist (in C++ sind höchstens das define NULL sowie ab C++11 auch der Null-Pointer-Wert nullptr üblich, null an sich gibt es nur dann, wenn es ein benutzerdefinierter Wert ist).

In Zeile 6 erstelltst du mit AudioInput(...) einen neue (temporäre!) Instanz von AudioInput, deren Wert du dann über den Zuweisungsoperator dem Objekt a zuweist. Ich sage temporär, weil diese neue Instanz sofort nach dem Durchlaufen des Zuweisungsoperators wieder aufhört zu existieren. Das Objekt a bleibt dann noch bis zum Ende der Funktion irgendeineMethode am Leben.
 
Zuletzt bearbeitet:
Mein C++ ist nicht so gut, um das aus dem Kopf beantworten zu können - du kannst es aber selbst ausprobieren: Mach dir einen Destruktor, der etwas nach stdout schreibt, und schau, ob es erscheint :)
 
Tockra schrieb:
Code:
void irgendeineMethode() {
      AudioInput a(...);
      ...
      a = null;
      // ist a jetzt zerstört?
      a = AudioInput(...); // neues a ?
}

Das ist kein C++ (wenn AudioInput eine Klasse ist). Du könntest zumindest eine kompilierbare Funktion hier anbieten ;)
 
Das Objekt a wird erst am Ende der Methode gelöscht (d.h. der Destruktur wird erst dann aufgerufen). Durch die Zuweisung a = AudioInput(...) ändert sich zwar der interne Zustand des Objekts a, aber das Objekt als solches bleibt bestehen.
 
blöderidiot schrieb:
Das ist kein C++ (wenn AudioInput eine Klasse ist).

Ich gehe davon aus, daß das bloß Pseudo-Code sein soll. Aber du hast schon Recht. Gerade in diesem Fall wäre es besser gewesen, der OP hätte echten, lauffähigen C++ Code vorgelegt.
 
Tockra schrieb:
Naja aber ich dachte Objekte werden gelöscht, sobald diese nicht mehr erreichbar sind (außer die im Heap). Wie lösche ich dann a ?



Dein a wird gelöscht (inkl. automatischem Destruktoraufruf), sobald du den Scope verlässt, in dem es erzeugt wurde. In dem Fall bedeutet das, beim Verlassen von irgendeineMethode.
 
destroy a;

Damit wird der Destruktor aufgerufen. Ansonsten nach Durchlauf der Funktion, da nur lokales Objekt.
 
Meines Wissens nach gar nicht.

Was im Stack liegt, kannst du nicht freigeben. Das ist da, bis der Stack abgebaut wird.
 
Du kannst die Erzeugung des Objekts z.B. mit einem eigenen Scope {} umrahmen.

Code:
void irgendeineMethode() {
    
    {
        AudioInput a(...);
    }

    // a existiert nicht mehr
}
 
Zuletzt bearbeitet:
Tockra schrieb:
Naja aber ich dachte Objekte werden gelöscht, sobald diese nicht mehr erreichbar sind (außer die im Heap). Wie lösche ich dann a ?

Tockra schrieb:
Wie kann ich es denn zerstören bevor ich das Ende der Methode erreiche, ohne jetzt die Klasse im Heap zu schmeißen und mit delete zu löschen?

Die Frage an sich und diese beiden Aussagen zeigen, dass du keine Ahnung von der Speicherverwaltung in C++ hast. Bitte mach dich darüber ausführlich schlau, bevor du irgendwas anderes machst; das wird sonst nämlich nichts.
 
Tockra schrieb:
Wie kann ich es denn zerstören bevor ich das Ende der Methode erreiche, ohne jetzt die Klasse im Heap zu schmeißen und mit delete zu löschen?
Geht nur so wie Du es nicht willst:
Code:
typedef AudioInput* AudioInputPtr;

void irgendeineMethode() {
   AudioInputPtr a = new AudioInput(1,2);

   // a = null; <== "dangling memory area", DON'T!

   delete a;
   // ist a jetzt zerstört?
   // ja

   a = new AudioInput(1, 2); // neues a ?
   // ja
}
Hast Du schon geahnt, richtig? Warum wäre das nicht machbar?
 
Ganz grob, was in dem Beispielcode mit a passiert:

Code:
void irgendeineMethode() {
      AudioInput a(...);    // AudioInput::AudioInput(...)
      ...
      a = null;             // Geht normalerweise nicht
      a = AudioInput(...);  // AudioInput::operator=(AudioInput&&)
}                           // AudioInput::~AudioInput()

Wie schon gesagt wurde, lokale Objekte werden am Ende des Scopes einfach zerstört, da muss - und kann - man sich nicht manuell drum kümmern.

Jetzt komme auch nicht auf die Idee und rufe den Destruktor manuell auf. Das geht zwar, ist aber nur in einem einzigen Fall legitim - nämlich wenn du deinen eigenen Memory Allocator schreibst.
Ansonsten würde es nämlich 2x zerstört werden, und rufst du ggf. Funktionen auf dem bereits zerstörten Objekt auf, das sich in einem undefinierten Zustand befindet.

Edit:
Da erzeugst du aber wieder ein Objekt auf dem Heap. Das kann zwar sinnvoller sein als die ganze Zeit lokale Objekte durch die Gegend zu schieben (und bei einer Klasse, die AudioInput heißt, gehe ich mal davon aus, dass dies der Fall ist), auch, wenn man nur Move- und keine Copy-Semantik implementiert - die Lösung von ph4nt0m trifft in dem Fall aber eher die Fragestellung.
 
Zuletzt bearbeitet:
VikingGe schrieb:
Da erzeugst du aber wieder ein Objekt auf dem Heap. Das kann zwar sinnvoller sein als die ganze Zeit lokale Objekte durch die Gegend zu schieben (und bei einer Klasse, die AudioInput heißt, gehe ich mal davon aus, dass dies der Fall ist), auch, wenn man nur Move- und keine Copy-Semantik implementiert - die Lösung von ph4nt0m trifft in dem Fall aber eher die Fragestellung.

Leider kennen wir die Fragestellung nicht wirklich. Ich vermute ein x-y-Problem.
 
nullPtr schrieb:
Die Frage an sich und diese beiden Aussagen zeigen, dass du keine Ahnung von der Speicherverwaltung in C++ hast. Bitte mach dich darüber ausführlich schlau, bevor du irgendwas anderes machst; das wird sonst nämlich nichts.

Vielen Dank für diese überhaupt nicht weiterhelfende Beteiligung. Ich habe schon einige Anleitungen für C++ gelesen und da kam auch immer wieder die Speicherverwaltung drin vor. Nun bin ich kein Computer und merke mir alles und habe zuletzt vor ein paar Wochen eine Anleitung gelesen. Aber zum Glück lernt man auch viel beim programmieren/testen und beim Fragenstellen im Forum.


Allen anderen danke ich sehr. Habe das dann doch durch einander geworfen. Es gibt eigentlich keinen speziellen Grund warum ich den Heap nicht benutzen sollte. Der Heap bringt nur überall Probleme mit sich welche man lösen muss (Speicherleaks). Das schreckt mich immer etwas vor der Benutzung ab, aber ich denke hier wird das legitim sein.
 
antred schrieb:
Sorry, meinte
delete a;

Sollte man aber vermeiden.
Hier wird erklärt, warum man es nicht machen sollte und schlägt andere Lösungswege vor.
 
Zuletzt bearbeitet:
amokkx schrieb:
Sorry, meinte
delete a;

Sollte man aber vermeiden.
Hier wird erklärt, warum man es nicht machen sollte und schlägt andere Lösungswege vor

Da steht was anderes. Da steht "you should simply delete the object rather than explicitly calling the destructor".
 
Zurück
Oben