Heap vs. Stack
-
Klasse* bummel = new Klasse;Die Instanz der Klasse liegt auf dem Heap... der Zeiger aufm Stack?
Klasse bummel;Die Instanz der Klasse liegt auf dem Stack.
Klasse* bummel;Zeiger aufm Heap, Klasse auch?
Was ist eigentlich sinnvoller anzuwenden?
Angenommen, Klasse wäre hier String, was sollte ich dann verwenden?
Das-String-Objekt speichert seine chars ja sicher aufm Heap, also bringt es was, das Objekt selbst auch auf den Heap zu werfen?Das Objekt auf dem Stack zu legen, hätte zumindest den Vorteil, dass man den Aufruf von delete nicht vergessen kann/muss.
Aber wie wäre es dann z.B. in eigenen Klassen. Da könnte ich das String-Objekt auf den Heap legen, weil es der Destruktor auf jeden Fall aufräumen wird.
-
Stacky schrieb:
Klasse* bummel = new Klasse;Die Instanz der Klasse liegt auf dem Heap... der Zeiger aufm Stack?
genau
Stacky schrieb:
Klasse bummel;Die Instanz der Klasse liegt auf dem Stack.
genau
Stacky schrieb:
Klasse* bummel;Zeiger aufm Heap, Klasse auch?
Zeiger aufm Stack, Instanz gibts keine
Stacky schrieb:
Was ist eigentlich sinnvoller anzuwenden?
Angenommen, Klasse wäre hier String, was sollte ich dann verwenden?
Das-String-Objekt speichert seine chars ja sicher aufm Heap, also bringt es was, das Objekt selbst auch auf den Heap zu werfen?Das Objekt auf dem Stack zu legen, hätte zumindest den Vorteil, dass man den Aufruf von delete nicht vergessen kann/muss.
Aber wie wäre es dann z.B. in eigenen Klassen. Da könnte ich das String-Objekt auf den Heap legen, weil es der Destruktor auf jeden Fall aufräumen wird.
Ich würde den string auf den Stack legen, vor allem, wie du schon gesagt hast, weil er sein sowieso auf den Heap legt.
Allgemein würde ich Instanzen von Klassen, die viel Speicher brauchen, eher auf den Heap legen, welche, die wenig brauchen, eher auf den Stack. Das kommt aber voll und ganz auf den Anwendungsfall an.
-
Die Regel ist eigentlich einfach: Zeiger so weit es geht vermeiden.
-
Die Regel ist eigentlich einfach: Zeiger so weit es geht vermeiden.
nein, zeiger sinnvoll einsetzen; es ist einfach schneller bei einer funktion einen zeiger zurückzugeben, als ein neues objekt zu erzeugen, das die gleichen attribute besitzt wie das auf das der zeiger zeigen würde
-
(das nächste Argument werden Referenzen sein)
-
TactX schrieb:
(das nächste Argument werden Referenzen sein)
...und programmiersprachen die ohne zeiger auskommen

-
net schrieb:
TactX schrieb:
(das nächste Argument werden Referenzen sein)
...und programmiersprachen die ohne zeiger auskommen

Gemeint sind hier: Programmiersprachen, die das Konzept der Zeiger vor dem Benutzer verstecken, also den Quellcode des Benutzers von Zeigern freihalten, wobei natürlich trotzdem Zeiger (besser vielleicht: Instanzadressen) verwendet werden.

Oder auch:
<Provokationsmodus>
Programmiersprachen, die davon ausgehen, daß ihre Benutzer so dämlich sind, daß sie mit Zeigern nicht umgehen können, so daß der Compiler das lieber selbst erledigt

</Provokationsmodus>
-
Man darf nicht vergessen, daß Objekte auf dem Stack wesentlich schneller anzulegen sind, als Speicher für den Heap zu allokieren!
Solls performant sein, um den Heap einen großen Bogen machen.
-
Außer natürlich, wenn das Allokieren vernachlässigbar ist gegenüber dem Konstruieren des Objekts.
-
hmmm
Base* myclass = new Child_of_Base;macht mir das mal auf dem stack!
-
Angan schrieb:
hmmm
Base* myclass = new Child_of_Base;macht mir das mal auf dem stack!
Child_of_Base cob_obj; Base *myclass = &cob_obj;
Den Heap sollte man natürlich benutzen, wenn man den Heap braucht. Der Stack hat natürlich schnelle Erzeugung und Freigabe, da er wie ein Stack funktioniert, aber sobald dieses Konzept für die Lebenszeit nicht mehr aussreicht, braucht man den Heap.
Der Stack ist außerdem verhältnismäßig klein im Gegensatz zum Heap.
-
rüdiger schrieb:
Der Stack ist außerdem verhältnismäßig klein im Gegensatz zum Heap.
Kannst Du da ne Angabe der Grössenordnung machen in MB? Oder ist das vom OS/Prozessor(32 vs. 64 bit) abhängig?
Nehme mal an, mit dem Heap kann man den kompletten Adressraum belegen, doch wie gross ist der Stack?
-
Wie du richtig erkannt hast, sind da verschiedene Faktoren zuständig. Du kannst ja einfach mal versuchen wie weit dein Stack geht:
int main () { char test [1000]; // und 1000 immer brav erhöhen :) return 0; }Meistens bietet der Linker Möglichkeiten die Stackgröße einzustellen.
MSDN für Visual C++ 2005 schrieb:
Durch die Option /STACK wird die Stapelgröße in Bytes festgelegt. Diese Option ist nur für die Generierung von EXE-Dateien vorgesehen.
Die Option gibt die gesamte Stapelreservierung im virtuellen Speicher an. Die standardmäßige Stapelgröße beträgt 1 MB. Der Linker rundet den angegebenen Wert auf die nächsten 4 Bytes auf.
MfG SideWinder
-
1310-Logik schrieb:
rüdiger schrieb:
Der Stack ist außerdem verhältnismäßig klein im Gegensatz zum Heap.
Kannst Du da ne Angabe der Grössenordnung machen in MB?
Stack: ca. 1-2 MB (von mehr sollte man nicht ausgehen)
Heap:
x86: ca. 1,7 GB
x64: ca. 8 TB
-
Wie kommst du auf die 1,7GB?
MfG SideWinder
-
SideWinder schrieb:
Wie kommst du auf die 1,7GB?
232-Verschleiß (OS)
-
Beispiel Linux-Kernel, 32bit, Standardkonfiguration. Der verfügbare Adressraum von 4 GB ist hier aufgeteilt auf 2 GB Kernelspace und 2 GB Userspace (der für jeden Prozess zur Verfügung steht). Abzüglich gemappten Speichers in den Kernel und diverser anderer Sachen, und abzüglich des Speichers den die Freispeicherverwaltung selbst braucht, um den Freispeicher zu verwalten, würde ich spontan (ohne wirklich genaue Werte ermittelt zu haben) auf ähnliche Dimensionen tippen. Das alles natürlich theoretisch, so dieser Speicher auch tatsächlich zur Verfügung steht.
@finix:
Dein OS "verschleißt" 2,3 GB?

-
LordJaxom schrieb:
Dein OS "verschleißt" 2,3 GB?

Ups! Du hast natürlich völlig Recht, das ist ne ganze Menge im Vergleich zu den ca. 2,3 GB in deinem Beispiel... :random-smiley:
-
finix schrieb:
LordJaxom schrieb:
Dein OS "verschleißt" 2,3 GB?

Ups! Du hast natürlich völlig Recht, das ist ne ganze Menge im Vergleich zu den ca. 2,3 GB in deinem Beispiel... :random-smiley:
in seinem beispiel verbraucht oder belegt es 2.3G
in deinem beispiel verbraucht oper ruiniert es 2.3G
ist zwar nicht ganz einfach ram zu verschleißen (als rechnerfüße benutzen und den rechner durch die wohnung schieben zum beispiel), aber verschlissener speicher ist kaputt.
ich denke, das meinte er. inhaltlich haste natürlich recht.
-
Danke Volkard. Genau das meinte ich, eine Übertreibung des Wortes Verschleiß in seinem eigentlichen Sprachgebrauch - Humor sozusagen
