Grundlegende Frage: nur objekt oder mit new
-
Hy,
ich hab mal ne grundlegende Frage: Was ist der entscheidende Vorteil, wenn man ein Oblekt nicht mit
<Klasse> <Objekt>;, sondern mit
<Klasse> *<Objekt>=new <Klasse>;definiert? Vllt. habt ihr sogar ein Bsp., wo es nur mit der Variante mit new geht, um den Vorteil zu erkennen?
-
Wird aufm Heap und das andere aufm Stack angelegt ...
achja ... ein Vorteil? du bist dynamisch!
-
Hya,

in diesem Fall hast du kein Vorteil.Durch die dynamische Erzeugung mit den new Operator hast du dir ein Nachteil eingekauft: Du musst dich um die Freigabe des Speicherplatzes selber kümmern.
Man benutzt den new Operator, wenn erst zur Laufzeit des Programms die Anzahl der zu erstellenden Objekte bekannt ist.

-
Hi,
ich tue mich schwer, "Vorteile" zu nennen .. es sind eher "Eigenschaften" von Heapobjekten. Spontan fallen mir ein:
- Erzeugung und Lebenszeit nicht an Scopes gekoppelt,
- üblicherweise steht auf dem Heap mehr Platz zur Verfügung.
... wie schon gesagt: Wenn Du mehrere Objekte (desselben Typs) anzulegen hast, kannst Du hier freier entscheiden, wie viele Du erzeugen möchtest als bei einem "klassischen Array". (aber "dynamischer" als ein std::vector ist das auch nicht ... allerdings nutzt der intern bestimmt auch new
da wird's dann philosophisch)Gruß,
Simon2.
-
Und wie kann man den Unterschied zwischen Heap und Stack genau definieren?
-
Alle Objekte, Variablen, etc. die du auf dem Heap erzeugst, bleiben so lange erhalten, wie das Programm läuft, oder bis du den Speicher mit new oder new [] freigibst.
Der Stack dagegen wird sozusagen automatisch Verwaltet:
Beim Eintritt in eine Funktion werden die Variablen, Parameter etc. automatisch auf den Stack gelegt, d.h. es wird Speicherplatz reserviert. Beim Verlassen der Funktion wird der dafür benötigte Speicherplatz automatisch freigegeben.Ich würde da nichts genau definieren wollen. Ob Stack oder Heap, beides ist Arbeitsspeicher, jedoch mit unterschiedlichem Verhalten.

-
Der feine Unterscheid schrieb:
...bis du den Speicher mit new oder new [] freigibst.....
Fehlerteufelchen sagt: "...delete oder delete [] ..."

Gruß,
Simon2.
-
Aaaah ja... Verstehe. (das meiste jedenfalls)
-
Simon2 schrieb:
Der feine Unterscheid schrieb:
...bis du den Speicher mit new oder new [] freigibst.....
Fehlerteufelchen sagt: "...delete oder delete [] ..."

Gruß,
Simon2.
Fehlerteufelchen hat völlig Recht !
Darum EDIT:
"...bis du den Speicher mit delete oder delete [] freigibst.....

-
Der feine Unterscheid schrieb:
...
Fehlerteufelchen hat völlig Recht !...Naja, war auch nicht wirklich schwer. War vermutlich jedem klar, was Du meintest, aber ich wollte es nur für den ungeübten Leser klarstellen.
Ach ja: Inhaltlich stimme ich Dir natürlich voll zu.Gruß,
Simon2.
-

-
Naja daten aufm Stack existiert ja nicht von anfang bis zum ende des Programmes (auser vll. Global oder static) , sondern nur so lange wie sie das Programm zu laufzeit in einen best Block (in der die variable deklaiert wird) arbeitet bspw. funktion..
void funk(){ int i; }somit lebt i ab "int i" bis zum ende des funktionsblocks.
wobei bei:
void funk(){ int *i= new int(); }ein int aufm heap angelegt wird, und über die funktion hinaus lebt, bis"delete bis "delete i;" aufgerufen wird... wichtig dabei ist, das man sich die adresse des aufm heap angelegen int's also der pointer i, sich solange merkt bzw. man damit den int wieder löscht.
-
wenn man
int main(){ int *i= new int(); i = NULL; }dass ist dieser new-integer für immer verschollen!!!!!
-
ich sagte ja das man sich die adresse der Objektes im Beispiel Pointer i merken sollten, wenn man die Adresse überschreibet mit NULL, dann ist es verschollen..
-
BorisDieKlinge schrieb:
Naja daten aufm Stack existiert ja nicht von anfang bis zum ende des Programmes (auser vll. Global oder static) , sondern nur so lange wie sie das Programm zu laufzeit in einen best Block (in der die variable deklaiert wird) arbeitet bspw. funktion..
Nur am Rande: globale und statische Variablen liegen nichtmal auf dem Stack (sondern im Data Segment)

wobei bei:
void funk(){ int *i= new int(); }ein int aufm heap angelegt wird, und über die funktion hinaus lebt, bis"delete bis "delete i;" aufgerufen wird... wichtig dabei ist, das man sich die adresse des aufm heap angelegen int's also der pointer i, sich solange merkt bzw. man damit den int wieder löscht.
So, wie du die Funktion geschrieben hast, ist das aber kein Beispiel für den richtigen Umgang mit dem Heap

Das int-Objekt liegt auf dem Heap und überlebt damit das Funktionsende. Der int-Zeiger liegt auf dem Stack und geht am Ende der Funktion verloren - ergo hast du ein sauberes Speicherleck.PS: Ja, die meisten Betriebssysteme holen sich allen angeforderten Heap-Speicher zurück, wenn dein Programm sich beendet, aber (a) können RL-Anwendungen etwas länger laufen und (b) werden auf diesem Weg keine Objekt-Destruktoren mehr aufgerufen (das Ergebnis sind im Ernstfall weitere Lecks, die häufig außerhalb des OS-Einflußes liegen).
-
Der Stack ist begrenz in seinem Speicher. VS hat da Standardm. 1 MB.
Braucht du mehr wird es eng.
-
stack und heap sind beides aufm Arbeitspeicher oder?
und trozdem ist da der stack begrenzt?
war frühr der stack nich driekt auf der CPU im cache oder so?
-
würd mich auch interessieren wie das wirklich wirklich genau funktioniert
was für ne kapazität hat stack?
-
Die Stackgröße kann beim Kompiler eingestellt werden. Das Maximum ist aber Betriebssystemabhängig.
-
BorisDieKlinge schrieb:
war frühr der stack nich driekt auf der CPU im cache oder so?
es gibt verschiedene arten von stacks.
für gewöhnlich haben CPUs mindestens einen stackpointer (ein internes register), den sie automatisch runterzählen, um die rücksprungadresse zu speichern wenn eine funktion aufgerufen und wieder hoch, wenn die funktion verlassen wird.
zusätzlich legen viele compiler für lokale variablen sogenannte stackframes an. dabei wird z.b. sizeof(alle_lokalen_variablen) vom stackpointer abgezogen und beim verlassen der funktion wieder dazu addiert.
...und meistens 'wachsen' solche stacks von oben nach unten.
