heap vs stack
-
hallo,
noch eine frage:
wenn ich eine klasse mit
Person p("hans");
oder
Person("hans");
instantiiere, landet die doch auf dem stack, oder?
Was passiert also hier:Person create() { Person p("hans peter"); return p; } ...in main: Person p = create(); cout << p.getName() << endl;wird p kopiert, im stack verschoben, so dass das objekt in der main methode verfügbar ist, oder...
mir ist aufgefallen, dass qt immer objekte direkt zurückgibt, nie pointer. wann verwendet man was?
danke
-
Ja, bei deinem Beispiel landen die Sachen auf dem Stack. Heap-Sachen verwendet man, um die Lebensdauer zu verlängern (mit new erzeugte Objekte werden ja nicht am Ende der Funktion destruiert) oder um eine Variable auf "leer" setzen zu können (Zeiger auf NULL).
In deinem Beispiel werden zwei Objekte vom Typ "Peter" erstellt, einmal in "create" und dann eins in "main". Verschoben werden Objekte nicht. Manchmal gibt's unkopierbare Typen, da bräuchtest du hier "new".
-
Rein Codemässig werden hier 2 Objekte erzeugt, allerdings darf man sich darauf nicht verlassen, da viele Compiler das wegoptimieren können.
Named return value optimization:
http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx
-
ah, danke.
und weiß jemand wie das in QT funktioniert? Es macht ja keinen sinn langlebige objekte wie widgets oder strings oder datenbankverbindungen auf dem stack zu speichern, aber es wird anscheinend so gemacht. Gibt es irgendeinen vorteil das objekt auf dem stack zu allokieren (auch noch 2 mal) wenn ich es öfters als in einer methode brauche?
-
Du solltest nicht in Stack und Heap denken, da dir das (von der Programmiererseite) egal sein kann. Wichtig ist der Unterschied von automatischem Speicher und dynamischem. Sprich automatischen (du nennst das Stack) Speicher musst du nicht selbst aufräumen. Der wird automatisch aufgeräumt. Und dynamischer (heap, also mit new allokierter Speicher) nicht. Das heisst, dass du dich da selbst um das aufräumen kümmern musst.
Somit sollte gelten, dass du solange, wie möglich automatischen Speicher benutzt, da das sicherer ist, als dynamischer. (Weil du keine Angst vor Memoryleaks/ungültigem Speicher haben musst).
-
ah vielen dank,
wann sollte ich dann überhaupt den dynamischen speicher benutzen?
könnte/sollte ich die ganzen new allokationen und die pointer aus meinem ersten beispiel (http://www.c-plusplus.net/forum/viewtopic-var-t-is-240144.html) also lieber entfernen?
danke
-
anfängerpeter schrieb:
ah vielen dank,
wann sollte ich dann überhaupt den dynamischen speicher benutzen?Dann, wenn du zum Zeitpunkt an dem du dein Programm schreibst noch nicht sagen kannst, wieviele Sachen gespeichert werden müssen.
-
Grundsätzlich solltest du dir das leben nicht schwerer machen, als es ist. Also nimm solange es geht automatischen Speicher und dynamischen nur, wenn du ihn wirklich brauchst. (Also wenn die Lebenszeit länger als der Scope sein soll, wenn die Grösser zur Kompilierzeit unbekannt ist oder aber auch bei polymorphie).
Es kommt halt ganz auf den Anwendungszweck an, ob du wirklich dynamischen Speicher brauchst. Sicher sinvoll ist es dynamischen Speicher irgendwie zu wrappen, wie es z.B
std::stringoderstd::vectortun, damit der Benutzer keine Probleme damit bekommt.
-
Es gibt noch ein anderes Problem. Dir steht als User nicht unbedingt ein umlimitierter Stack zur Verfuegung, jedoch ein ein heute nahezu unlimitierter Heap. Grosse Datenmengen werden deshalb besser im Heap allociert (new-Operator oder C-Style mit malloc/calloc), um hier einen Stack-Overflow zu vermeiden.