Warum Speicher mit new reservieren?



  • Hi@all,
    mein Praktikant fragt mich wo der Vorteil liegt den Speicher mit new zu reservieren. Mir fehlen da ehrlich gesagt die Worte bzw. krieg ich es nicht hin im da so zu erklären das er es versteht. Hat jemand ne Erklärung für Laien bzw. Anfänger?

    Gruß CrazyPlaya



  • der vorteil gegenüber dem anlegen auf dem stack? gegenüber alloc, gegenüber dem schreiben aller daten auf hdd? ...

    rapso->greets();



  • Vielleicht fehlen Dir die Worte, weil es keinen Vorteil gibt 😃

    Es hängt doch stark von der Situation ab, ob es wirklich sinnvoller Daten auf dem Heap abzulegen.

    Die einzige echte Erklärung, die mir so spontan einfällt, ist, das die zur Verfügung stehende Speichermenge für den Stack beschränkter ist (und früher sehr beschränkt war). Daher wurde früher immer geraten möglichst wenig Daten auf dem Stack abzulegen.



  • Man reserviert eben speicher mit new.
    Ohne Speicher wird ein Programm nicht funktionieren.

    Legt man eine Klasseninstanz auf dem Stack an (ohne new) geht es auch aber es kann passieren das nicht genug Speicher auf dem Stack übrig bleibt. Dieser ist pro Programmstart begrenzt. Bei VS z.B. Standardm. auf 1 MB

    Mit New wird speicher auf dem Heap reserviert. Dadurch hast du soviel Speicher wie eben der Rechner hat bzw. das BS dir liefern kann.

    Ich aber bedenklich das du so eine Antwort (new bzw. Speicherreservierung) nicht einem Pratikanten selbst sagen kannst.



  • Ich will ja nichts sagen, aber du weißt es einfach selbst nicht. 👎 Wer etwas nicht erklären kann, hat es selber nicht verstanden. Finde es armsehlig sich jetzt rausreden zu wollen. Gib doch einfach zu "Ich weiß es auch nicht.". Wenn es im Detail nicht stimmt, ist es nicht so schlimm, dann kann man es korrigieren. Aber garnicht erklären, das einem die Worte fehlen??? 😮

    Es gibt eindeutige Unterschiede und eindeutige Vor- und Nachteile zwischen Stack und Heap. Kann man alles auf meiner Homepage nachlesen.



  • @Artchi

    Dies ist ein typischer Fall wo man dann doch schreiben sollte wen du meinst.



  • Sorry, meinte CrazyPlaya, den Threadstarter.



  • Der arme Praktikant... es gibt hier kein besser oder nicht besser. Wenn ich nicht will, dass etwas tot ist sobald der Stackframe abgebaut wird, kann ich es halt nicht auf dem Stack anlegen. Man muss sich Gedanken über die Lebenszeit des Objekts machen.



  • Hmm, in DEM Design Patterns Buch von Gamma & Konsorten ist ein Beispiel einer Factory, die da heißt "LabyrinthFabrik" (Sorry, hab nur die deutsche Ausgabe als buch =)). Eine LabyrinthFabrik kann verschiedene Dinge, z.B. Räume und Wände erzeugen. (Das sind wiederum auch alle Klassen). Die erstellung sieht dann z.B. so aus:

    Wand* LabyrinthFabrik::ErzeugeWand(...) {
      return new Wand(...);
    }
    

    Eine wand erstellen wir dann so:

    Wand* wand = fabrik.ErzeugeWand(...);

    Ist zwar jetzt stark gekürzt und man mag auch nicht sofort den Kontext erkennen..
    Allerdings finde ich das schon am Wortlaut "new Wand" gut nachzuvollziehen, auch wenn es evtl. der falsche Weg ist. Mir fällt gerade keine Lösung ein, wie man das mit dem Stack machen könnte, habe es auch noch nicht ausprobiert.



  • Optimizer schrieb:

    Wenn ich nicht will, dass etwas tot ist sobald der Stackframe abgebaut wird, kann ich es halt nicht auf dem Stack anlegen. Man muss sich Gedanken über die Lebenszeit des Objekts machen.

    exakt 👍

    mit new erzeuge ich Objekte mit dynamischer Lebensdauer, d.h. die Lebensdauer hängt nicht von der statischen Blockstruktur des Programms ab, sondern von den Zeitpunkten, zu denen sich der Programmierer entschließt, das Objekt zu erzeugen bzw. zu zerstören.

    Weitere Aspekte dieser Dynamik: Man kann den Typ zur Laufzeit festlegen (siehe Factory-Muster), bei Arrays die Größe.



  • Artchi schrieb:

    Ich will ja nichts sagen, aber du weißt es einfach selbst nicht. 👎 Wer etwas nicht erklären kann, hat es selber nicht verstanden. Finde es armsehlig sich jetzt rausreden zu wollen. Gib doch einfach zu "Ich weiß es auch nicht.". Wenn es im Detail nicht stimmt, ist es nicht so schlimm, dann kann man es korrigieren. Aber garnicht erklären, das einem die Worte fehlen??? 😮

    Hier sind soviel schöne Erklärungen die ich ihm auch schon erklärt habe, aber trotz der vielen Threads hier versteht er es immer noch nicht so richtig, hat nichts damit zu tun, das ich es selber nicht weiß sondern das er es nicht nicht versteht. Und deshalb fehlten mir die Worte, weil ich einfach nihct merh wusste wie ich es ihm verständlicher erklären soll.



  • Nicht jeder ist zum Programmierer berufen...
    Wenn er es nicht kapiert, ist er evtl. einfach
    ungeeignet für die Aufgabe 🙄



  • Oder Assembler lernen, dann weiß man, warum es da Unterschiede gibt.





  • Was gibts da großartig nicht zu verstehen 😕

    1. Der Stack ist beschränkt in seiner Größe, große Objekte müssen auf den Heap.
    2. Der Stack baut sich bei Scope-Ende wieder ab, wenn du Objekte über Scope-Grenzen hinaus benützen willst benötigst du den Heap
    3. Nur mit dynamischen Speicher kannst du dynamisch Objekte anlegen und so tolle Dinge wie Polymorphie benützen

    MfG SideWinder



  • SideWinder schrieb:

    3. Nur mit dynamischen Speicher kannst du dynamisch Objekte anlegen und so tolle Dinge wie Polymorphie benützen

    Nein, Polymorphie hat damit nichts zu tun.



  • Direkt nicht, aber indirekt muss man auf Heap-Speicher zurückgreifen. Kenne zumindest selbst keine Möglichkeit mit Stack-Objekten Polymorphie zu betreiben.

    // afaik nicht möglich:
    Base base = Derived();
    

    MfG SideWinder



  • Zum Beispiel geht sowas:

    void foo(Base& base) {
        base.methode();
    }
    

    Wo das Objekt jetzt liegt, ist egal.



  • Derived a;
    Base *b = &a;
    

    Für Polymorphie braucht man nur virtuelle Funktionen und die Möglichkeit, Basisklassenzeiger (oder -referenzen) auf abgeleitete Objekte zeigen zu lassen.



  • SideWinder schrieb:

    3. Nur mit dynamischen Speicher kannst du dynamisch Objekte anlegen [...]

    Du kannst ja auch den Stack dynamisch allokieren. In C++ gibt es da zwar keine Standard Methode für, aber in C99 gibt es ja VLA und einige Betriebssysteme stellen Funktionen wie man: alloca(3) zur Verfügung.

    include <alloca.h>
    
    struct foo { };
    
    int main() {
      foo *ptr=new (alloca(sizeof(foo)))foo;
    }
    

Anmelden zum Antworten