Verständnisfragen zu new Element() und Destruktoren



  • Und das hat wiederrum zur Folge, dass Arbeitsspeicher auf dem Heap verloren geht - je nach Compiler entweder nur zur Laufzeit oder bei älteren Modellen bis zum Neustart des Computers, wo der RAM ja sowieso hopps geht. 😉



  • wobei modernere betriebssysteme den destruktor automatisch beim verlassen des programmes aufrufen.
    aber es bleibt weiterhin ein schlechter programmierstil, wenn man die objekte nicht selbst zerstört



  • danke das ist mir schon klar das man sie löschen sollte, es ging hier um übungen zur vererbung in denen zu befehlen die ausgaben rausgesucht werden sollten, und ich wollte nur sichergehen das ich die destruktor ausgaben bzw aufrufe ( es war jeweils ein cout in allen methoden ) richtig verstanden habe



  • daersc schrieb:

    wobei modernere betriebssysteme den destruktor automatisch beim verlassen des programmes aufrufen....

    hmmmm, wirklich?
    Also dass ein OS den Speicher wieder freiräumt und ggf. andere OS-verwaltete Ressourcen freigibt (Filehandles, ...), mag ich ja noch glauben. Aber einen Dtor, der vielleicht noch andere "Aufräumarbeiten" erledigt, aufzurufen, traue ich ihm nicht zu.
    Vielleicht packt das eine ausgefeilte Runtimelib ... aber spätestens bei ausgefeilten Abhängigkeiten (bei denen z.B. die Reihenfolge wichtig ist) wird das auch nicht klappen.

    Gruß,

    Simon2.



  • Ich glaube er bezog sich dabei eher auf die Destruktoren die vorhanden sind. Wobei Speicher freigeben der mit new erzeugt wurde ja ansich auch geht man könnte ihn in void* lagern und dann freigeben, das wäre zwar nicht ganz korrekt würde doch aber eigentlich nen Teil des Lecks verhindern?



  • tallan schrieb:

    das heisst wenn Myklasse einen Desktruktor implementiert hat wird dieser am ende nicht auferufen sondern ich muss explizit z.b per delete a; das objekt löschen ?

    Wenn du Objekte auf dem Stack (automatische Speicherklasse) anlegst, werden deren Destruktoren beim Verlassen des Gültigkeitsbereiches (in umgekehrter Deklarationsreihenfolge) aufgerufen:

    int main()
    {
        Myklasse a;
        {
            Myklasse c;
        } // hier wird c zerstört.
        Myklasse b;
    } // hier wird zuerst b und dann a zerstört.
    

    Xebov schrieb:

    Wobei Speicher freigeben der mit new erzeugt wurde ja ansich auch geht

    Natürlich geht das, ganz konventionell mit delete . Worauf willst du hinaus? Drück dich genauer aus.



  • Xebov schrieb:

    Ich glaube er bezog sich dabei eher auf die Destruktoren die vorhanden sind. ...

    Wer ".. bezog sich dabei ..."?
    Und was sind "...Destruktoren die vorhanden sind..." ? (dass nicht vorhandene vom OS auch nicht aufgerufen werden, finde ich jetzt wenig überraschend)

    Gruß,

    Simon2.



  • Xebov schrieb:

    Wobei Speicher freigeben der mit new erzeugt wurde ja ansich auch geht

    Natürlich geht das, ganz konventionell mit delete . Worauf willst du hinaus? Drück dich genauer aus.[/quote]

    Du hast das etwas aus dem Zusammenhang gerissen, ich bezog mich auf Simons Post und wolte damit sagen das ein OS ja evtl tracken könnte welchen Ram das Programm belegt und den rest der nach dem beenden übrig bleibt freigeben köntne von alleine.

    Simon2 schrieb:

    Xebov schrieb:

    Ich glaube er bezog sich dabei eher auf die Destruktoren die vorhanden sind. ...

    Wer ".. bezog sich dabei ..."?
    Und was sind "...Destruktoren die vorhanden sind..." ? (dass nicht vorhandene vom OS auch nicht aufgerufen werden, finde ich jetzt wenig überraschend)

    Wenn ich mit new etwas erzeuge wäre ein Destruktor nicht automatisch vorhanden wenn ich kein delete benutze denn das Objekt lebt ja nach dem beenden als Leck weiter, so meinte ich das.



  • Xebov schrieb:

    Du hast das etwas aus dem Zusammenhang gerissen, ich bezog mich auf Simons Post und wolte damit sagen das ein OS ja evtl tracken könnte welchen Ram das Programm belegt und den rest der nach dem beenden übrig bleibt freigeben köntne von alleine.

    Sorry, der Kontext war mir nicht gleich klar. In der Praxis wird ein Programm beim Beenden den zugesicherten Speicher wieder an das Betriebssystem zurückgeben, vermute ich (also müsste nicht jede Anforderung vom OS selber getrackt werden). Aber besser ist es, man lässt es gar nicht darauf ankommen. Wenn man komplexere Abhängigkeiten hat, können Smart Pointer und RAII sehr nützlich sein.

    Xebov schrieb:

    Wenn ich mit new etwas erzeuge wäre ein Destruktor nicht automatisch vorhanden wenn ich kein delete benutze denn das Objekt lebt ja nach dem beenden als Leck weiter, so meinte ich das.

    Vorhanden (als Funktion) ist der Destruktor trotzdem, auch wenn er nicht aufgerufen wird - es sei denn, du implementierst ihn nicht, was normalerweise aber niemand macht...

    Hm, hat das deine Fragen ungefähr beantwortet? Tut mir leid, wenn meine Antworten zu unpräzise sind, aber deine Fragen waren es auch. 🙂


  • Administrator

    Xebov schrieb:

    Wenn ich mit new etwas erzeuge wäre ein Destruktor nicht automatisch vorhanden wenn ich kein delete benutze denn das Objekt lebt ja nach dem beenden als Leck weiter, so meinte ich das.

    Da fehlen Satzzeichen.
    Ich habe probiert, diese selber einzufügen.
    Ich bin gescheitert.
    Und ich habe auch immer noch nicht verstanden, was du sagen willst.

    Mit kurzen Sätzen kannst du dies vielleicht besser klarstellen.
    Verschachtelte Sätze können schnell zu komplex werden.
    Dies gilt vor allem, wenn man keine Satzzeichen verwendet.
    Oder wenn man zu wenig Satzzeichen verwendet.

    Grüssli 😃



  • Nexus schrieb:

    Hm, hat das deine Fragen ungefähr beantwortet? Tut mir leid, wenn meine Antworten zu unpräzise sind, aber deine Fragen waren es auch. 🙂

    Es war mehr son Mix aus Frage und Feststellung aber macht nix, hab mich da wohl etwas zu ungünstig ausgedrückt.

    Dravere schrieb:

    ...

    😃

    Ich hätte echt Quoten sollen, seite 1 Simons Post.
    OK der Post von Simon wegen dem automatischen Aufruf des Betriebssystems. Da wolte ich dazu sagen das der auf den sich Simon bezog wohl nur existente aufrufbare Destruktoren meint (oder kurz RAII) und nicht Destruktoren die nicht von alleine Aufgerufen werden (wegen new) durchs OS oder wo auch immer. Und habe danach gesagt es wäre ja auch Möglich das das OS den Speicher der Anwendung Trackt und ihn danns elbst freigibt denn das OS weis ja wann sich das Programm verarbschieded hat. Hatte es nur nicht gequotet deswegen war wohl unklar worauf ich mich bezogen hatte.

    So ich hoffe nun kann man mich verstehen. Und wegen den Satzzeichen ich dachte eigentlich es wären genügend da, achja ich liebe verschachtelte Sätze :D.


  • Administrator

    Xebov schrieb:

    So ich hoffe nun kann man mich verstehen.

    Ich zweifle langsam an mir selber. Ich versteh den Inhalt deiner Sätze einfach nicht ...

    Ich nehme mal einfach dein ursprünglicher Satz, welcher sich auf Simon2s Aussage gleich vor deinem Beitrag bezog und stelle dazu Fragen. Zudem füge ich fett hervorgehoben ein paar Korrekturen, bzw. Satzzeichen, ein. Nur damit ich sehe, ob ich die Sätze auch richtig verstehe 🙂

    Xebov schrieb:

    Ich glaube**,** er bezog sich dabei eher auf die Destruktoren**,** die vorhanden sind. Wobei Speicher freigeben**,** der mit new erzeugt wurde**,** ja ansich auch geht**.** Man könnte ihn in void* lagern und dann freigeben, das wäre zwar nicht ganz korrekt**,** würde doch aber eigentlich nen Teil des Lecks verhindern?

    • Was sind Destruktoren, welche vorhanden sind? Jede Klasse in C++ hat automatisch auch einen Destruktor.
    • Ja, man kann eine Speicheradresse in void* speichern. Aber wie willst du den Speicher dann freigeben? Ein delete auf einen void -Zeiger geht nicht. Ein free aus der C Bibliothek ruft undefiniertes Verhalten hervor.
    • Simon2 hat ja nicht gesagt, dass ein OS kein Speicher freigeben kann. Er hat gesagt, dass keine Destruktoren aufgerufen werden. Dazwischen gibt es einen grossen Unterschied.

    Grüssli 😕

    PS: Ich bin kein Rechtschreib- oder Grammatikfanatiker. Ich mache auch viele Fehler, aber bei dir ist das schon ... naja 🙂



  • Xebov schrieb:

    ...Wenn ich mit new etwas erzeuge wäre ein Destruktor nicht automatisch vorhanden ...

    😕 Der Destruktor ist Bestandteil der Klassendefinition....
    seine Existenz hat mit der Art, wie ein Objekt dieser Klasse erzeugt wird, nichts zu tun.

    Sag doch einfach: "Ich habe mich falsch ausgedrückt. Was ich wirklich meinte war <xyz>".
    Oder noch besser: "Ich weiß auch nicht, was daersc gemeint hat." (denn eigentlich ging es um seinen Kommentar, das OS riefe selbständig Destruktoren auf)

    ...und bitte nicht als "o ich glaub da hab ich irgendwie aber ihr wisst ja schon falsch oder so destruktor gemeinte Sache genannt aber ist ja alles ganz anders..." 😉

    Auch ich bin kein Orthographie- oder Grammatikfanatiker, aber es gibt EINE (einfach einzuhaltende) Regel, deren Einhaltung Lesen und Verstehen um den Faktor 1000 vereinfacht (bzw. tw. erst ermöglicht):
    Sätze durch Satzzeichen trennen!!
    (Auch und gerade Nebensätze! Dafür hat der liebe Gott Kommata erfunden).

    Wenn Du Dir dann noch angewöhnst, nicht beliebig "Füllsel" ("so", "mein ich", "ja", ...) reinzuwerfen, dann werden alle hier NOCH motivierter sein, Dein Anliegen zu verstehen und zu unterstützen. 😃

    Gruß,

    Simon2.



  • Dravere schrieb:

    Ich zweifle langsam an mir selber. Ich versteh den Inhalt deiner Sätze einfach nicht ...

    Also ich hab da keine Probleme, mag die machtd er Gewohnheit sein.

    [quote="Dravere"]

    • Was sind Destruktoren, welche vorhanden sind? Jede Klasse in C++ hat automatisch auch einen Destruktor.
    • Ja, man kann eine Speicheradresse in void* speichern. Aber wie willst du den Speicher dann freigeben? Ein delete auf einen void -Zeiger geht nicht. Ein free aus der C Bibliothek ruft undefiniertes Verhalten hervor.
    • Simon2 hat ja nicht gesagt, dass ein OS kein Speicher freigeben kann. Er hat gesagt, dass keine Destruktoren aufgerufen werden. Dazwischen gibt es einen grossen Unterschied.

    1. ja natürlich hat sie das aber für den Automatischen aufruf existiert er nur wenn das Objekt nicht per new angelegt wurde denn solche Objekte werden ja nicht automatisch zerstört sondenr nur per delete damit existeriert er zwar durch die deffinition da aber existiert für das Programm selbst nicht da es ja über keine Möglichkeit verfügt das Objekt automatisch selbst zu löschen
    2. damit beschäftige ich mich nich, das war nur ein Gedankenanstoß
    3. Das hab ich ja auch nie behauptet, ich war nur der Meinung er hatte den Post auf den er sich bezog falsch verstanden.

    Dravere schrieb:

    PS: Ich bin kein Rechtschreib- oder Grammatikfanatiker. Ich mache auch viele Fehler, aber bei dir ist das schon ... naja 🙂

    Ja ich weis, ist nix neues, ich gebs auch erstmal auf, ich glaube nämlich das wir hier schon ähnliches Meinen aber uns irgendwie nicht ganz verstehen.



  • Xebov schrieb:

    Also ich hab da keine Probleme, mag die machtd er Gewohnheit sein.

    Die Aussage des Tages.

    1. ja**,** natürlich hat sie das**.** Aber für den Automatischen aufruf existiert er nur**,** wenn das Objekt nicht per new angelegt wurde**.** Denn solche Objekte werden ja nicht automatisch zerstört sondenr nur per delete**.**

    Das ist quatsch. Gerade Objekte, die automatisch erzeugt werden, werden auch automatisch zerstört.

    Damit existeriert er zwar durch die deffinition [da], aber [existiert] für das Programm selbst nicht**,** da es ja über keine Möglichkeit verfügt das Objekt automatisch selbst zu löschen

    Siehe oben.

    ich glaube nämlich das wir hier schon ähnliches Meinen aber uns irgendwie nicht ganz verstehen.

    Wundert Dich das? Beziehungsweise, merkst Du wie die oben eingestreuten Kommas und Punkte (die Großschreibung habe ich schon nur nach dem Punkt betrachtet) die Lesbarkeit steigern?


  • Administrator

    Xebov schrieb:

    Also ich hab da keine Probleme, mag die machtd er Gewohnheit sein.

    Dass du deine Sätze verstehst, erstaunt mich nicht. Du weisst ja auch, was du sagen willst, hoffe ich zumindest 😃

    Xebov schrieb:

    1. ja natürlich hat sie das aber für den Automatischen aufruf existiert er nur wenn das Objekt nicht per new angelegt wurde denn solche Objekte werden ja nicht automatisch zerstört sondenr nur per delete damit existeriert er zwar durch die deffinition da aber existiert für das Programm selbst nicht da es ja über keine Möglichkeit verfügt das Objekt automatisch selbst zu löschen

    Die Dinger sind aber trotzdem vorhanden und existieren auch. Sie werden einfach nicht für das entsprechende Objekt aufgerufen, wenn man eben dieses per new angelegt hat.
    Aber ich verstehe nicht so recht, was du damit sagen wolltest. Simon2 hat ja auch nichts anderes behauptet.

    Xebov schrieb:

    2. damit beschäftige ich mich nich, das war nur ein Gedankenanstoß

    Anstoss wofür? Worauf wolltest du hinaus?

    Xebov schrieb:

    3. Das hab ich ja auch nie behauptet, ich war nur der Meinung er hatte den Post auf den er sich bezog falsch verstanden.

    Inwiefern soll er ihn falsch verstanden haben?

    Xebov schrieb:

    Ja ich weis, ist nix neues, ich gebs auch erstmal auf, ich glaube nämlich das wir hier schon ähnliches Meinen aber uns irgendwie nicht ganz verstehen.

    Bitte nicht aufgeben, wir kriegen das noch hin, ich streng mich auch an 🙂
    Bin irgendwie wahnsinnig neugierig darauf, was es am Ende war. Das ist wie ein Weihnachtsgeschenk, welches man einfach nicht aufkriegt 😃

    Grüssli



  • LordJaxom schrieb:

    Xebov schrieb:

    ich glaube nämlich das wir hier schon ähnliches Meinen aber uns irgendwie nicht ganz verstehen.

    Wundert Dich das? Beziehungsweise, merkst Du wie die oben eingestreuten Kommas und Punkte (die Großschreibung habe ich schon nur nach dem Punkt betrachtet) die Lesbarkeit steigern?

    Ich hoffe du bist nicht böse wenn ich sage nein, ich habs schließlich geschrieben also wäre es ja peinlich wenn ichs selbst nicht lesen könnte.

    Dravere schrieb:

    Xebov schrieb:

    Ja ich weis, ist nix neues, ich gebs auch erstmal auf, ich glaube nämlich das wir hier schon ähnliches Meinen aber uns irgendwie nicht ganz verstehen.

    Bitte nicht aufgeben, wir kriegen das noch hin, ich streng mich auch an 🙂
    Bin irgendwie wahnsinnig neugierig darauf, was es am Ende war. Das ist wie ein Weihnachtsgeschenk, welches man einfach nicht aufkriegt 😃

    Grüssli

    Naja freut mich das ich da für Spannung sorge. 😃

    Aber ich denke trotzdem wir lassen das Thema mal ruhen. Sonst wird das ganze zu Spekulativ, denn was könnte jemand falsch Interpretiert haben usw das bringt nix.



  • Xebov schrieb:

    ...
    3. Das hab ich ja auch nie behauptet, ich war nur der Meinung er hatte den Post auf den er sich bezog falsch verstanden....

    Wie hättest Du denn das hier:

    tallan schrieb:

    ...
    nehmen wir folgenden code :

    Myklasse * a = new Myklasse();

    ...
    2) wird der Konstruktor aufgerufen, nach beendigung des programms aber kein explizit deklarierte destruktor ?!...

    =>

    daersc schrieb:

    wobei modernere betriebssysteme den destruktor automatisch beim verlassen des programmes aufrufen....

    anders verstanden?

    Ich persönliche vermute ja, dass daersc meinte: "Moderne Betriebssysteme geben nach Beendigung Einer Anwendung automatisch den Speicher wieder frei, selbst wenn die Anwendung keine Freigabe beantragt hat."

    Das ist aber eben nicht dasselbe wie der Aufruf eines Destruktors ... und (nur) um Letzteres drehte sich hier die ganze Frage.

    Gruß,

    Simon2.

    P.S.: Ich glaube ein Problem hier im Forum ist, dass es bei diesem Thema seeeeehr um Genauigkeit geht. Deswegen fallen leichte "Formulierungsschwächen" hier ebenso viel schneller aus dem Rahmen wie auch ein Schreibstil, der in in anderen Foren vielleicht vollkommen in Ordnung ist (und sich dort angewöhnt wurde).


  • Administrator

    Xebov schrieb:

    Aber ich denke trotzdem wir lassen das Thema mal ruhen. Sonst wird das ganze zu Spekulativ, denn was könnte jemand falsch Interpretiert haben usw das bringt nix.

    Es ist deine Entscheidung. Ich frage mich einfach, ob du womöglich nicht etwas falsch verstanden hast. Also ob du etwas in C++ falsch verstehst. Daher wäre es vielleicht auch für dich sinnvoll, wenn man dies sauber ausarbeiten würde.

    Grüssli



  • Ok, ich hole mal die Posts zusammen, hoffe ich erwische alle.

    daersc schrieb:

    wobei modernere betriebssysteme den destruktor automatisch beim verlassen des programmes aufrufen.
    aber es bleibt weiterhin ein schlechter programmierstil, wenn man die objekte nicht selbst zerstört

    ->

    Simon2 schrieb:

    daersc schrieb:

    wobei modernere betriebssysteme den destruktor automatisch beim verlassen des programmes aufrufen....

    hmmmm, wirklich?
    Also dass ein OS den Speicher wieder freiräumt und ggf. andere OS-verwaltete Ressourcen freigibt (Filehandles, ...), mag ich ja noch glauben. Aber einen Dtor, der vielleicht noch andere "Aufräumarbeiten" erledigt, aufzurufen, traue ich ihm nicht zu.

    So darauf hab ich mich bezogen, auf Simons Post der sich auf daersc Post bezog. Ich bin davon ausgegangen das Daersc einfach RAII meint. Und nicht irgendwelche Extras.

    Deswegen hab ich auch geschrieben das er wohl nur für das Programm existente Destruktoren meint, also kurz die die durch RAII erfasst werden denn die die von new Objekten stammen kommen ja nicht ohne delete zum Aufruf, ich hoffe das ist jetzt verständlich, es geht dabei nicht um die Frage ob der Destruktor da ist oder nicht, denn natürlich ist er imemr da, sondern um die Sicht des Programms auf das Objekt.

    Danach hab ich mich auf die Aufräumarbeiten bezogen und angemerkt das ein OS durchaus den Speicher des Programms Tracken könnte und ihn freigeben köntne wenn das Programm stirbt, oder die Teile eben durch Schlamperei oder Fehler nicht freigegeben wurden. Damit würde es weitere Aufräumarbeiten übernehmen.

    So ich hab mich diesmal echt bemüht und hoffentlich genug Satzzeichen drin das es jeder lesen kann.


Anmelden zum Antworten