new & delete Sinn & Zweck



  • Weil durch new Speicher am HEAP reserviert wird, und ned am STACK wie ohne new.
    Google mal nach HEAP und STACK, jedenfalls hat ein Programm meist nur sehr begrenzt STACK zur Verfügung.

    Das klingt zwar logisch aber ich habe es noch nie erlebt, dass für ein Programm nicht genug Speicher zur Verfügung stand.
    Obwohl mir gerade einleuchtet, warum so viele große Compiler, wie Borland alle Objekte, wie Buttons, Grafiken oder sounds immer mit dem new Operator erstellen.
    Ich hatte diese Frage hier im Forum auch schonmal gepostet aber diese Erklärung erscheint mir wensentlich sinnvoller als alle anderen genannten Gründe.

    Badestrands Beispiel seh ich mir jetzt mal genauer an...-.-



  • Der Grund, warum bei Borland-Compilern alle VCL-Objekte mit new erstellt werden, ist darin begründet, dass man hier die Polymorphie intensiv nutzt. Das geht zwar theoretisch auch mit Referenzen, aber eben nicht bei der VCL, da die in Pascal programmiert ist.



  • Ich hatte diese Frage hier im Forum auch schonmal gepostet aber diese Erklärung erscheint mir wensentlich sinnvoller als alle anderen genannten Gründe.

    Ist sie aber nicht.
    Wenn du nicht verstehst wann und warum man mit new/delete arbeitet (arbeiten muss, und das ganz unabhängig davon ob einem der Speicher ausgehen könnte), dann kann ich dir wahrscheinlich auch nicht helfen.
    Das ist eine Sache die so logisch ist wie es nur geht.

    Wenn du die Lebenszeit eines Objektes "mit Hand" kontrollieren können musst, brauchst du eben new/delete. Und Fälle wo das nötig ist gibt es einige.



  • Machen wir's doch mal ganz einfach. Schreib ohne 'new' und 'delete' ein Programm, das vom Benutzer eine Zahl n einliest (das geht schonmal nicht ohne Zeiger, aber tun wir mal so als ob das ginge), dann vom Benutzer eine n*n große Matrix einliest (wie auch immer) und zum Schluss die ersten zwei Spalten aufeinanderaddiert und ausgibt.



  • Konrad Rudolph schrieb:

    ...ein Programm, das vom Benutzer eine Zahl n einliest (das geht schonmal nicht ohne Zeiger, ...

    Wo braucht man denn da Zeiger ?

    int i;
    cin >> i;
    

    😕

    Das Andere stimmt zwar prinzipiell, aber da viele new/delete-Unerfahrene sowieso immer mit "impliziten Maximallängen" arbeiten, kann dieser Schuss schnell nach hinten losgehen. 😉
    Aber prinzipiell stimmt natürlich, dass man in C++ dynamisch lange Arrays nicht auf dem Stack sondern nur auf dem Heap anlegen kann.

    Wenn ich richtig sehe, hatten wir das Thema schonmal unter dem Titel "Wofür Heap ?"... und da war das Ergebnis:
    Heap dann, wenn
    - Speicher auf dem Stack nicht reicht (z.B. große Datenmengen),
    - Arraylänge zur Compilezeit nicht bekannt (natürlich kann man StdLib-Container verwenden ... aber spätestens die brauchen dann auch new)
    - Objekte müssen über ihren Scope hinaus gültig sein.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Heap dann, wenn
    - Speicher auf dem Stack nicht reicht (z.B. große Datenmengen),
    - Arraylänge zur Compilezeit nicht bekannt (natürlich kann man StdLib-Container verwenden ... aber spätestens die brauchen dann auch new)
    - Objekte müssen über ihren Scope hinaus gültig sein.

    - Erst zur Laufzeit bekannt ist, ob oder von welchem Typ ein Objekt erstellt werden soll
    🙂



  • Simon2 schrieb:

    Konrad Rudolph schrieb:

    ...ein Programm, das vom Benutzer eine Zahl n einliest (das geht schonmal nicht ohne Zeiger, ...

    Wo braucht man denn da Zeiger ?

    int i;
    cin >> i;
    

    😕

    Konzeptuell braucht man da hinter den Kulissen Zeiger. „Rohe“ Zeiger benutze ich persönlich ja eh nie und dementsprechend auch kein 'new' bzw. 'delete'.



  • Konrad Rudolph schrieb:

    Simon2 schrieb:

    Konrad Rudolph schrieb:

    ...ein Programm, das vom Benutzer eine Zahl n einliest (das geht schonmal nicht ohne Zeiger, ...

    Wo braucht man denn da Zeiger ?

    int i;
    cin >> i;
    

    😕

    Konzeptuell braucht man da hinter den Kulissen Zeiger.

    Also es ist zwar schon ne weile her, dass ich sowas mal mit Assembler gemacht hab, aber an nen Zeigen kann ich mich nicht erinnern.
    Vom Prinzi hat es etwas so ausgesehen (ohne fehlerbehandlung).

    zahl = 0
    read:
    interrupt für tastendruck //ergebnis steht z.B. in reg ax
    if ax == ENTER jump ende
    zahl += ax - '0'
    zahl *= 10
    jump read
    ende:
    

    Mit dem Streamgedöns braucht man wahrscheinlich schon nen Zeiger, aber um ne Zahl einzulesen eigentlch nicht.



  • Konrad Rudolph schrieb:

    ...Konzeptuell braucht man da hinter den Kulissen Zeiger. ...

    Also ichglaube weder, das das hier gefragt ist (es geht um new/delete und nicht um "Zeiger hinter den Kulissen"), noch dass diese Definition von "Zeiger" allzuviele C++-Programmierer teilen.
    Ich sehe da auschließlich Referenzen am Werk, die in C++ eigene (und zwar andere) Dinge sind als Zeiger.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Konrad Rudolph schrieb:

    ...Konzeptuell braucht man da hinter den Kulissen Zeiger. ...

    Also ichglaube weder, das das hier gefragt ist (es geht um new/delete und nicht um "Zeiger hinter den Kulissen"), noch dass diese Definition von "Zeiger" allzuviele C++-Programmierer teilen.

    Okay. Unter diesen Voraussetzungen *muss* die Antwort auf die originale Frage aber lauten „man braucht sie gar nicht.“ Alles andere ist eine falsche und gefährliche Antwort.

    Abgesehen davon habe ich die Frage aber schon so verstanden, dass es darum ging, wozu man diese Konstrukte konzeptuell benötigt (und dass die Frage einfach schlecht / ungenau formuliert war).



  • Konrad Rudolph schrieb:

    ...
    Okay. Unter diesen Voraussetzungen *muss* die Antwort auf die originale Frage aber lauten „man braucht sie gar nicht.“ Alles andere ist eine falsche und gefährliche Antwort....

    Was ist denn daran:

    Heap dann, wenn
    - Speicher auf dem Stack nicht reicht (z.B. große Datenmengen),
    - Arraylänge zur Compilezeit nicht bekannt (natürlich kann man StdLib-Container verwenden ... aber spätestens die brauchen dann auch new)
    - Objekte müssen über ihren Scope hinaus gültig sein.
    - Erst zur Laufzeit bekannt ist, ob oder von welchem Typ ein Objekt erstellt werden soll

    falsch und gefährlich ?

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Konrad Rudolph schrieb:

    ...
    Okay. Unter diesen Voraussetzungen *muss* die Antwort auf die originale Frage aber lauten „man braucht sie gar nicht.“ Alles andere ist eine falsche und gefährliche Antwort....

    Was ist denn daran:

    Heap dann, wenn
    - Speicher auf dem Stack nicht reicht (z.B. große Datenmengen),
    - Arraylänge zur Compilezeit nicht bekannt (natürlich kann man StdLib-Container verwenden ... aber spätestens die brauchen dann auch new)
    - Objekte müssen über ihren Scope hinaus gültig sein.
    - Erst zur Laufzeit bekannt ist, ob oder von welchem Typ ein Objekt erstellt werden soll

    falsch und gefährlich ?

    Das, was ich fett hervorgehoben habe.

    Du hast mir weiter oben selbst vor die Füße geworfen, dass es hier *nicht* um gekapselte Speicherallokationen geht. Du hast recht, dass man Heap-Speicher am laufenden Band braucht. Aber mit der expliziten Benutzung von 'new' und 'delete' (insbesondere letzterem) hat das nichts zu tun.

    In dieser Hinsicht habe ich mich, seitdem ich Meyers gelesen habe, wirklich zum Speicher-Nazi entwickelt. 'delete' ist gefährlich und unnötig und kommen in meinen Quellcodes gar nicht mehr vor, und 'new' nur noch in Verbindung mit Smart Pointers o.ä.

    Ich möchte übrigens hervorheben, dass das nichts mit „Anfängerproblemen“ oder so zu tun hat. 'delete' macht es einfach so gut wie unmöglich, effizienten und Exception-sicheren Code zu schreiben.



  • Konrad Rudolph schrieb:

    ...
    Du hast mir weiter oben selbst vor die Füße geworfen, dass es hier *nicht* um gekapselte Speicherallokationen geht. ...

    Nö, habe ich nicht.
    Ich habe Dir "vor die Füße geworfen", dass man "Zeiger hinter den Kulissen" (also da, wo der Compiler Referenzen als Zeiger implementiert) nicht braucht.
    ... und das auch nur als Reaktion auf Deine Aussage: "Zeiger braucht man beim Einlesen eines Wertes".
    Ich bestreite weder, dass man Zeiger braucht (da, wo "kopierbare Verweise" benötigt werden), noch dass man new/delete besser gekapselt nutzt - nur, dass das Einlesen eines Wertes Zeiger braucht.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Konrad Rudolph schrieb:

    ...
    Du hast mir weiter oben selbst vor die Füße geworfen, dass es hier *nicht* um gekapselte Speicherallokationen geht. ...

    Nö, habe ich nicht.
    Ich habe Dir "vor die Füße geworfen", dass man "Zeiger hinter den Kulissen" (also da, wo der Compiler Referenzen als Zeiger implementiert) nicht braucht.

    Ich spielte aber gar nicht auf die Referenzen an sondern darauf, dass die Auslese-Routine betriebssystemintern garantiert irgendwelche Zeiger verwenden wird. Lass es zur Not Zeiger auf die entsprechenden Funktionen aus dem Kernel sein (also unter Windows ntdll-Einsprungadressen).

    Ist ja auch egal. Wie gesagt, wir gingen von unterschiedlichen Voraussetzungen aus. Ich hatte gedacht, dass nach dem konzeptuellen Sinn von Zeigern gefragt war, Du hattest das anscheinend konkreter auf 'new' und 'delete' bezogen.



  • Konrad Rudolph schrieb:

    ...Ich spielte aber gar nicht auf die Referenzen an sondern darauf, dass die Auslese-Routine betriebssystemintern garantiert irgendwelche Zeiger verwenden wird. ...

    Ach so.

    Konrad Rudolph schrieb:

    ...Ich hatte gedacht, dass nach dem konzeptuellen Sinn von Zeigern gefragt war, Du hattest das anscheinend konkreter auf 'new' und 'delete' bezogen.

    Stimmt.
    Irgendwie wies mir so gar nicht sin die Richtung "Zeiger":

    777 schrieb:

    ...
    Habe mich gerade mal ein bisschen mit dynamischer Speicher und Heap-Adressierung auseinander gesetzt und bin dort auf die Schlüsselwörter new und delete gestossen.

    Im Internet habe ich erfahren, dass der new-Ausdruck einen Zeiger auf einen Speicherbereich zurückgibt.
    ...
    Was genau bringt uns die new-Anweisung?
    Warum nicht einfach mit normalen Zeigern und normalen Objekten arbeiten?
    ...

    ... zumal der letzte Satz darafu hinweisen könnte, dass der OP den Sin von Zeigern durchaus kannte.

    Naja, egal.

    Gruß,

    Simon2.


Anmelden zum Antworten