Der Martin: Stack und Heap

Beitrag lesen

Hi,

„Kreis k; // statische Erzeugung
Statisch bedeutet hier, dass C++ das Objekt auf dem Stack speichert.“
Die Verwendung von "statisch" ist reichlich unklug, denn unter diesem Attribut versteht man bei OOP etwas gänzlich anderes als das eine Variable (und auch ein Objekt ist eine Variable) einfach auf dem Stack abgelegt wäre.

und noch allgemeiner (etwa in C oder Assembler) versteht man unter "statisch" wieder etwas anderes - nämlich Variablen, deren Speicheradresse und Speicherbedarf bereits beim Compilieren festgelegt wird.

„Diese statische Erzeugung ist übrigens eine Spezialität von C++. Andere Sprachen, wie Pascal/Delphi, C#, Visual Basic(.NET) und Java kennen keine statisch erzeugten Objekte. In diesen Sprachen werden Objekte immer dynamisch erzeugt.“
Das ist in dieser Form schlicht und ergreifend – falsch. Das ist sowas von falsch, man sollte dem Mann das Schreiben von Lehrtexten zur Programmierung verbieten. Entweder schreibt man von Objekten, dann hat die Sprache Pascal (und Visual Basic?) da aber nichts zu suchen, denn die kennt keine Objekte

Aber hallo! Moderne Pascal-Varianten kennen sehr wohl Objekte und Klassen. Schon Borland Pascal 7 aus dem Jahr 1990 (so ungefähr jedenfalls) kannte das Konzept von Klassen und OOP, und Delphi, das davon abstammt, erst recht. Für Wuschelbasic will ich mich da nicht aus dem Fenster lehnen, das kenne ich nur vom Hörensagen.

oder man bezieht sich auf Variablen allgemein, dann stimmt die Behauptung, der Stack wäre eine Spezialität von C++ aber nicht.

Die stimmt sowieso nicht. Der Stack ist ein Grundkonzept fast aller CPUs, das von vielen Programmiersprachen übernommen und mitgenutzt wird.

  1. Der Stack, zu Deutsch Stapelspeicher.

Danke, dass du nicht Kellerspeicher sagst. Der Begriff kursierte Anfang der 90er Jahre, als man plötzlich sämtliche EDV-Fachtermini mit Gewalt eindeutschen wollte, mal in diversen Fachbüchern, und Scharen von Programmierern haben sich gefragt, was das wohl sein mag.

Rufst du eine Funktion A auf, in der du beispielsweise ein int i deklariert hast, benutzt die Funktion A vier Bytes des Stapelspeichers. Ruft diese Funktion A eine weitere Funktion B auf, stapelt die zweite ihre Variablen auf die bereits vorhandenen Variablen von A. Und so geht das immer weiter, mit jedem Aufruf kommen weitere Variablen auf den Stapel, mit jedem Verlassen einer Funktion schrumpft der Stapel wieder.
Diese Variablen leben und sterben also mit dem Funktionsaufruf. Wohlgemerkt: Aufruf. Ruft A sich selbst auf, stapelt der zweite Aufruf von A seine Variablen auf jenen des ersten Aufrufs von A.

Das ist soweit richtig, aber all das ist nur eine Sekundärnutzung des Stacks. Der Hauptzweck ist, Rücksprungadressen beim Aufruf von Unterprogrammen (Funktionen) zu speichern, um die Ausführung des Programms nach dem "return" an der richtigen Stelle fortsetzen zu können.

  1. Der Hauptspeicher (der Autor nennt ihn Heap). Du kannst explizit Hauptspeicher vom Betriebssystem anfordern, meinetwegen wieder vier Bytes für dein int. Du bekommst dann vom System die Adresse des Speicherbereichs, kannst über diese Adresse auf die Bytes zugreifen und musst den Speicher wieder freigeben, sobald du ihn nicht mehr brauchst.

Und du bekommst meistens mehr Speicher, als du eigentlich anforderst. Windows teilt beispielsweise Speicher nur in Portionen von 4kB zu; wenn die Anwendung also 24 Bytes anfordert, bekommt sie 4kB. Das ist aber systemabhängig.

Der Unterschied zwischen Stack und Hauptspeicher (Heap) liegt für dich als Programmierer einfach in deinem Bedarf. Der Stack enthält mehr oder weniger alle lokalen Variablen einer Funktion.

Außerdem ist der Stack bei manchen Rechnerplattformen begrenzt. Auf 16bit-Systemen wie DOS oder Windows 3.x und älter kann der Stack maximal 64kB groß werden, bei 32bit-Systemen kann er theoretisch 4GB umfassen, wenn das OS nicht von sich aus eine Bremse reinhaut.

So long,
 Martin

--
Chef:         Zum vierten Mal in dieser Woche erwische ich Sie nun schon beim Zuspätkommen. Was haben Sie dazu zu sagen?
Angestellter: Dann muss heute Donnerstag sein.
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(