Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Heap und Stack - Unterschiede (https://www.delphipraxis.net/162461-heap-und-stack-unterschiede.html)

-187- 23. Aug 2011 21:32


Heap und Stack - Unterschiede
 
Moin, ich hab mal ne Frage bezüglich "Heap und Stack" !

Also was ist denn eigentlich der Heap und was ist der Stack ? Recherchen im Netz waren -für mich- widersprüchlich. Kann mir jemand in eigenen Worten erklären was der wesentliche Unterschied ist und welche Variablen vom Stack und welche vom Heap verwaltet werden ?

Danke schonmal für eure Antworten,

Ciao!

implementation 23. Aug 2011 21:42

AW: Heap und Stack - Unterschiede
 
Den Stack als Datenstruktur kannst du dir wie einen Stapel vorstellen.
Wenn du oben was draufgepackt hast (push) kannst du auch nur das oberste Element wieder runternehmen (pop) oder es dir anschauen (peek).

Der Stack als Speicherbereich ist in etwa so aufgebaut wie die gerade erwähnte Datenstruktur:
Mit den Assemblerbefehlen push und pop können Bytes draufgeschoben werden.
Entgegen der bildlichen Vorstellung eines Stapels wächst er jedoch nach unten.
Auf den Stack kommt alles, was verschachtelt wird:

> Funktion A wird aufgerufen mit Argument B
>> Return-Pointer kommt auf den Stapel
>> B kommt auf den Stapel
>> A macht was mit B
>> Funktion A wird rekursiv aufgerufen mit Argument C
>>> Return-Pointer kommt auf den Stapel
>>> C kommt auf den Stapel
>>> A macht was mit C
>>> Stapel wird bereinigt
>>> Return-Pointer wird gepopt
>> Stapel wird gereinigt
>> Return-Pointer wird gepopt
> und wir sind wieder im Hauptprogramm

Verstanden?

Bummi 23. Aug 2011 21:42

AW: Heap und Stack - Unterschiede
 
ich meine
http://de.wikipedia.org/wiki/Dynamischer_Speicher
liefert eine verständliche Erklärung

ehX 23. Aug 2011 21:42

AW: Heap und Stack - Unterschiede
 
Der Heap ist der Speicher, den du für dynamische Speicherzuweisungen verwendest. Dieser hat so viel "Platz" wie dein System noch frei hat.
Der Stack hat dagegen einen feste Grösse und ist vieeel kleiner als der Heap, dafür aber wesentlich schneller und so aufgebaut wie ein LiFo-Puffer.
Im Stack werden lokale Variablen und generell alles, was temporär zur Laufzeit einer Routine (calls by value etc.) an Speicher benötigt wird, abgelegt.
Im Heap sind die Allokationen persistenter, d.h., jeglicher Speicher, den du anforderst (malloc und Konsorten) landet im Heap.

BUG 23. Aug 2011 21:55

AW: Heap und Stack - Unterschiede
 
Der Stack (auf Deutsch: "Stapel") wird hauptsächlich für Funktionen genutzt: Argumente übergeben, lokale Variablen speichern, Rücksprungadresse und nicht-flüchtige Register speichern.
Der Stack wird im Internet eigentlich meist korrekt beschrieben.

Beim Heap (auf Deutsch: "Haufen") kann es gut Verwirrungen geben.
Gemeint sein kann: eine Datenstruktur mit Heap-Eigenschaft, ein binärer Heap oder eben eben der Speicherbereich, aus dem man Speicher reservieren kann.
Du meinst den Letzten.
In diesem Speicher kann man Bereiche bestimmter Größe anfordern und ein Algorithmus sucht dafür einen freien Platz (z.B. mit getMem in Delphi).
Die Heapverwaltung kann sehr unterschiedlich organisiert sein.

-187- 23. Aug 2011 21:56

AW: Heap und Stack - Unterschiede
 
Danke für eure Informationen. Dann kommen zum Beispiel Stringlisten (TStringList) auf den Heap weil die Größe ungewiss ist ?

//Edit: @implementation, tolle Erklärung, Dankeschön!

Bummi 23. Aug 2011 22:07

AW: Heap und Stack - Unterschiede
 
wenn Dich das ganze wirklich interessiert, damm schau Dir mal ein paar Assemblercodeblöcke an, ich durfte damit groß werden, nativer siehst nirgends was wirklich passiert.

ConnorMcLeod 24. Aug 2011 04:29

AW: Heap und Stack - Unterschiede
 
Zitat:

Zitat von -187- (Beitrag 1119123)
Dann kommen zum Beispiel Stringlisten (TStringList) auf den Heap ?

Ja

Zitat:

Zitat von -187- (Beitrag 1119123)
weil die Größe ungewiss ist ?

Nein, sondern, weil es angeforderter Speicherbereich ist.

himitsu 24. Aug 2011 05:56

AW: Heap und Stack - Unterschiede
 
Auf den Stack kommen vorallem lokale Variablen, Rücksprungadressen der Prozeduraufrufe und Stackframes.

Dynamische Arrays, "lange" Strings (also alles außer Delphi-Referenz durchsuchenShortStrings und statischen Char-Arrays), Objekte und Interfces sind intern Zeiger, also liegen dann maximal ihre Zeiger auf'm Stack und der Rest im Heap, da dessen Speicher intern z.B. über GetMem angefordert wird.

Globale Variablen und typisierte Konstanten liegen in der DataSektion der EXE/DLL.
"Echte" Konstanten landen meißt in der CodeSektion, bzw. werden ja direkt in den Nutzungsstellen wertmäßig eingebaut.
Felder/Membervariablen von Objekten, da dieses ja in dem Objekt liegen, landen somit auch auf dem Heap landen.


Deshalb bekommt man gerne mal Probleme (Stacküberlauf) bei:
- zirkulären Prozeduraufrufen / Endlosschleifen
- zu großen statischen Arrays

DeddyH 24. Aug 2011 07:24

AW: Heap und Stack - Unterschiede
 
Zitat:

Zitat von himitsu (Beitrag 1119147)
Auf den Heap kommen vorallem lokale Variablen, Rücksprungadressen der Prozeduraufrufe und Stackframes.

:?:

sirius 24. Aug 2011 07:48

AW: Heap und Stack - Unterschiede
 
Zitat:

Zitat von himitsu (Beitrag 1119147)
Auf den HeapStack kommen vorallem lokale Variablen, Rücksprungadressen der Prozeduraufrufe und Stackframes.

(Goreckdur (das Dicke) von mir)



Zitat:

Zitat von himitsu
Globale Variablen liegen im Heap

Die liegen in der Data-Section vom Programm. Da hier kein (zusätzlicher) Speicher reserviert oder irgendetwas freigegebenen werden kann, würde ich dies nach der Definition von Heap nicht als Heap bezeichnen.
Deswegen:
  • globale Variablen -> Im Programmcode (Data-Section)
  • lokale Variablen -> Stack (ggf. auch nur im Prozessor/Register)
  • der ganze Rest an Speicher -> Heap
Ansonsten ist schon alles gesagt. Auf dem Stack landen neben den lokalen Variablen noch:
  • Übergabeparameter (wenn nicht im Prozessor/Register) an Funktionen
  • Rücksprungadressen
  • Exception-Frames (jedes mal wenn man try aufruft, biss das finally oder except kommt)
  • der Inhalt von Registern, der mal kurzfristig zwischengespeichert werden muss
Für den Stack hat die Intel-Architektur (nicht nur die) auch spzielle Befehle (push und pop) für deren Nutzung, oder Befehle, die den Stack gleich mal mitbenutzen (call, ret)


Im Grunde genommen passiert bei der Programmausführung folgendes:
Die EXE (inkl. aller benötigten, statisch eingebundenen DLLs) wird in den Speicher geladen. Damit sind schon mal alle globalen Variablen (die ja mit ihrem Initialisierungswert schon in der EXE direkt drin stehen) im Speicher. Bei den globalen Variablen kannst du deswegen zwar jederzeit deren Inhalt ändern, aber nie deren Speicherplatz freigeben.
Die nächste spannende Speicheraktion kommt, wenn dein Programm (im Mainthread) gestartet wird. Dann bekommst du (bei Standardeinstellung) 16kB Speicher reserviert. Im Prozessoer gibt es dafür dann ein Register (kleiner Speicherplatz) namens ESP, der dir zeigt wo der Stack liegt und der auch von solchen Befehlen wie push, pop, call und ret enstsprechend genutzt wird. Darauf landen, wie gesagt, die lokalen Variablen und diverses schon Genanntes.
Und was jetzt noch (von den 2GB virtuellem Adressraum) übrig ist, nennt sich Heap, auf dem du dich austopben kannst. Das heißt, du kannst jederzeit von Windows Speicher anfordern (was u.a. getmem für dich erledigt, welches auch von jedem Constructor TKlasse.Create genutzt wird) und den frei für Daten nutzen und jederzeit asuch wieder an Windows zurückgeben.

Soweit von mir...

gammatester 24. Aug 2011 07:56

AW: Heap und Stack - Unterschiede
 
Zitat:

Zitat von himitsu (Beitrag 1119147)
Auf den Heap kommen vorallem lokale Variablen, Rücksprungadressen der Prozeduraufrufe und Stackframes.s

Du solltest mal ausschlafen! :wink: Das Zeug kommt doch hoffentlich auch bei Dir auf den Stack (Sonst würde es wohl auch besser Heapframe heißen).

himitsu 24. Aug 2011 08:25

AW: Heap und Stack - Unterschiede
 
korrigiert :oops:

-187- 25. Aug 2011 13:55

AW: Heap und Stack - Unterschiede
 
Alles klar, Dankeschön an alle !:)

jdelphi 26. Mai 2014 15:19

AW: Heap und Stack - Unterschiede
 
Sodele ich betätige mich mal als Leichenschänder.

Seit ihr euch sicher das Lokale Variablen im Stack landen?

Wenn ich eine Lokale Variable ändern will, muss ja dann der ganz stack bis zur Variable hinauf geppopt werden, die Variable geändert und anschließend schön brav wieder alles zurück pushen. Vor allem woher weiß die CPU den noch an welcher stelle im Stack die Variable beerdigt liegt.

Vielleicht ist aber mit lokaler Variable was anderes gemeint, als ich meine.

Code:
procedure TForm1.Button1Click(Sender: TObject);
var
 lokale  : integer;
 variable : String;
begin

end;

PS: Warum wird eigentlich String Fett abgebildet und Integer als Normalschrift?

himitsu 26. Mai 2014 15:28

AW: Heap und Stack - Unterschiede
 
Ja, sind wir.

Die lokalen Variablen, Rücksprungungadressen usw. werden auf den Stack gepusht und beim Verlassen der Prozeduren wieder gepoppt.

Aber der Zugriff auf die darauf befindlichen Inhalte geht direkt, über die relative Adresse zum aktuellen Stackpointer.


Im Prinzip hat dieser Stack meistens eine feste Größe (MinStackSize bis MaxStackSize) und es gibt nur einen/zwei Stack-Pointer (ESP und EBP), für die aktuelle Position im Speicher ... an der Stelle werden neue Werte draufgepusht und dabei der Pointer verschoben.


[add]
String ist ein "Reservierter Bezeichner"
www.bergt.de/workshop/delphi/html/delphi33.htm http://delphi.programmieren.vias.org...ved_words.html

Sir Rufo 26. Mai 2014 15:29

AW: Heap und Stack - Unterschiede
 
Der Stack passt doch perfekt. Beim Aufruf werden die Parameter und dann die lokalen Variablen auf den Stack gelegt
Code:
variable : string
lokale : integer
Sender : TObject
Rücksprung-Adresse
...
Innerhalb der Prozedur weiß der Rechner, dass sich
Delphi-Quellcode:
lokale
an der Stelle Stack-1 und
Delphi-Quellcode:
variable
an Stack-0 befindet.

Wird diese Prozedur jetzt erneut aufgerufen, dann
Code:
variable : string
lokale : integer
Sender : TObject
Rücksprung-Adresse
variable : string
lokale : integer
Sender : TObject
Rücksprung-Adresse
...
passt das doch wie die Faust aufs Auge ;)

jdelphi 26. Mai 2014 15:45

AW: Heap und Stack - Unterschiede
 
Ok stimmt, man kann den Stack ja auch per Pointer und MOV.. beschreiben und lesen.
Hierdurch wird der Stackpointer nicht Inc/Dec.

Push und Pop hilft verändert ja bequemer weiße den SP mit.

Ok ich glaub ich habs jetzt auch *g*

PPS: Und warum ist Integer kein Reserviertes Wort.
Das interessiert mich schon seit Jahren.

p80286 26. Mai 2014 15:53

AW: Heap und Stack - Unterschiede
 
Das wiederum wäre ein neues Thema!

Gruß
K-H

Stevie 26. Mai 2014 16:13

AW: Heap und Stack - Unterschiede
 
Zitat:

Zitat von jdelphi (Beitrag 1260302)
PPS: Und warum ist Integer kein Reserviertes Wort.

Die Frage ist wohl eher: warum ist string eins!? 8-)

Dejan Vu 26. Mai 2014 20:45

AW: Heap und Stack - Unterschiede
 
Zitat:

Zitat von Stevie (Beitrag 1260313)
Die Frage ist wohl eher: warum ist string eins!? 8-)

Weil es nicht zwei sein kann. Ist doch logisch. :stupid:

String ist ein Systemtyp, Integer nicht, sondern nur eine Ausprägung des Ordinaltyps.
Oder: "string" ist ein reserviertes Schlüsselwort, "Integer" nur ein vordefinierter Datentyp.

himitsu 27. Mai 2014 07:42

AW: Heap und Stack - Unterschiede
 
[edit] wo? :mrgreen:

Sir Rufo 27. Mai 2014 07:47

AW: Heap und Stack - Unterschiede
 
@himitsu

Falscher Thread, Guten Morgen :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz