Wo ist der Stack



  • Hallo
    man liest immer wieder mal was von Stack und das man da was drauf legen soll.
    Ich habe mich mal informiert und weiß das der Stack ein Stapel im Prozessorregister ist auf dem mal was drauf legt und wieder entnehmen kann.
    Meine Frage ist also wie realisiere ich das?
    Wie lege ich was auf den Stack drauf und wie bekomme ich es wieder runter?
    Ist es notwendig so was zu machen und macht es Sinn es selber zu tun.
    Ich habe das schon öfters hier im Forum gelesen

    .... pack es doch auf den Stack ....

    Deswegen frage ich mich das.
    Danke im voraus.
    Gruß



  • Alles was du nicht mit new oder malloc oder etwas ähnlichem anforderst, liegt auf dem Stack

    Beispiele

    class foo { int i,j; public: /*...*/ };
    
    int main() {
     foo a; //Stack
     foo *b=new foo; //FreeStore/Heap
     int j; //Stack
     int *k=new int[10]; //FreeStore/Heap
     int l[100]; //Stack
     foo c[2]; //Stack
    
     //...
    }
    


  • definieren für int

    stack<int> intStack;
    

    definieren für objekte

    stack<Objekt> objStack;
    

    int ablegen

    intStack.push(5);
    

    objekte ablegen

    Objekt myObj(...);
    ...
    objStack.push(myObj);
    

    int-werte auslesen

    int val = intStack.top();
    

    objekte auslesen

    Objekt objOne(...);
    objOne = objStack.top();
    

    obersten!!! stack entfernen

    intStack.pop();
    

    oberstes!!! objekt entfernen (ausführen des destructors)

    objStack.pop();
    

    alles weitere kannst du auch in einem buch oder google erfahren 😋



  • @enno es ist der speicherbereich stack gemeint, nicht das objekt 😉

    @kingruedi mit new erstellter speichre ist auf dem heap, mit malloc erstellter speicher auf dem freestore, wie mir gesagt wurde, ist da ein unterschied.

    @topic jede normale variable liegt auf dem stack, erst wenn so sachen wie new oder malloc ins spiel kommen, kommt man vom stack weg, deshalb mach dir mal keine sorgen



  • otze schrieb:

    @kingruedi mit new erstellter speichre ist auf dem heap, mit malloc erstellter speicher auf dem freestore, wie mir gesagt wurde, ist da ein unterschied.

    war die Bezeichnung nicht andersrum?



  • otze schrieb:

    @kingruedi mit new erstellter speichre ist auf dem heap, mit malloc erstellter speicher auf dem freestore, wie mir gesagt wurde, ist da ein unterschied.

    Dieser Unterschied würde mich mal interessieren. Wo soll da ein Unterschied sein?



  • Ok, danke erst mal für die Antworten.
    Ich habe nur ein Verständnisproblem noch.
    Wenn eine Variable auf dem Stack abgelegt wird und anschließend noch eine dann komme ich ja immer nur an die oberste dran. Wenn ich aber an die darunter liegende dran kommen will, wie mach ich das denn? Wer entscheidet das?
    Ich schätze mal das ich (als Programmierer) da wenig zu melden habe.
    Das wäre ja ein Aufwand wenn man vom Stapel erst alles wegräumen muss um dann an die geforderte Variable dran zu kommen und diese anschließend wieder auf den Stack zu legen.
    Sind das die Compiler die ein Programm so organisieren das nur das auf den Stack gelegt wird was unmittelbar nötig ist oder macht das der Prozessor selber?
    Ich habe eben noch gelesen das man deshalb am besten nur lokale Variablen erzeugen soll damit nicht unnötige 'Bewegungen' statt finden die ja zu diesem Problem führen.
    Eventuell verstehe ich aber einfach die Zusammenhänge noch nicht richtig.

    Trotzdem Danke noch mal für die Mühe.



  • gib jeder variable einen eindeutigen namen, oder hole sie über eine schleife raus



  • Ponto schrieb:

    otze schrieb:

    @kingruedi mit new erstellter speichre ist auf dem heap, mit malloc erstellter speicher auf dem freestore, wie mir gesagt wurde, ist da ein unterschied.

    Dieser Unterschied würde mich mal interessieren. Wo soll da ein Unterschied sein?

    Das einzige Mal, dass ich diesen Unterschied genannt gesehen habe, war in Herb Sutters "Exceptional C++". Und dort heisst es, dass new den Freestore benutzt und malloc den Heap, also umgekehrt zu otzes Aussage.



  • CarstenJ schrieb:

    Das einzige Mal, dass ich diesen Unterschied genannt gesehen habe, war in Herb Sutters "Exceptional C++". Und dort heisst es, dass new den Freestore benutzt und malloc den Heap, also umgekehrt zu otzes Aussage.

    Was ist dann der Unterschied zwischen Heap und Freestore?



  • Glaubst du nicht, dass er einfach zwei verschiedene Begriffe verwendet hat, um Wiederholungen zu vermeiden? Oder hat er explizit den Unterschied herausgestellt?



  • Eine nicht gerade überzeugende Differenzierung finde ich auf der Seite:

    http://www.devx.com/tips/Tip/13757

    Die meisten anderen Links, die ein "gg: freestore heap" ergibt, differenzieren die Begriffe nicht.



  • Es ist legal für new malloc zu verwenden um den Speicher anzufordern - das sollte die Unterschiede doch klären, oder? 😉

    Nämlich: es gibt keinen. Bei new nennt es sich halt Freestore und bei malloc Heap.



  • Es ist legal für new malloc zu verwenden um den Speicher anzufordern

    Daraus ergibt sich der Freestore darf im Heap sein. Das bedeutet aber nicht, das die beiden gleichbedeutend sind. Vielleicht kann man den Freestore besonders aufbauen, um schnellere Allokationen von kleinen Objekten zu erlauben, statt von großen oder so.



  • Der Unterschied ist, dass free store ein fester Begriff des C++ Standards und Heap nicht.
    Im C++ Standard werden im Kapitel 12.5 Free store die Eigenschaften von new/delete beschrieben und bestimmte Bedingungen festgelegt.
    Gleichzeitig sagt der Standard, dass:
    a) malloc, calloc, realloc, free nicht über new/delete implementiert werden dürfen,
    b) zwischen new/delete und *alloc/free keinerlei Beziehung bestehen muss.

    Wir haben also einen festen Begriff "free store" auf der einen Seite und Memory-Management-Funktionen malloc, calloc, realloc, free auf der anderen Seite.
    Der C-Standard vergibt keinen festen Namen für den Bereich auf dem malloc und Co arbeiten. Da dieser Bereich aber praktisch immer als Heap implementiert ist, heißt er Heap. Der Name ist aber eigentlich auch irrelevant.

    Wichtig ist die Tatsache, dass new/delete und malloc/free auf konzeptionell unterschiedlichen Speicherbereichen arbeiten, dass der von new/delete "free store" heißt und dass beide Bereiche nicht austauschbar sind.

    Deshalb ist es an der Grenze zwischen C und C++ wichtig zwischen free store und Heap zu unterscheiden. Betrachtet man hingegen sowieso nur new/delete ist diese Unterscheidung imo überflüssig. Auch der free store ist praktisch immer als Heap implementiert und von daher spricht in diesem Fall nichts gegen eine Aussage wie "new allokiert Speicher auf dem Heap".

    PS: Aber bis auf den letzten Teil steht das letztlich doch alles auch in Sutters "Exceptional C++" 🙄



  • @Stackpointer

    Ich habe nur ein Verständnisproblem noch.
    Wenn eine Variable auf dem Stack abgelegt wird und anschließend noch eine dann komme ich ja immer nur an die oberste dran. Wenn ich aber an die darunter liegende dran kommen will, wie mach ich das denn? Wer entscheidet das?

    Aehm das ding heisst ned Stack, weil die Variablen im Code wie ein STack behandelt werden, sondern die Funktionsbloecke ... Also der Speicher in Abhaengigkeit vom Ablauf erweitert und wieder dezimiert wird.
    Das Tut der compiler und das BS fuer dich ...

    Musst dir das so vorstellen :

    int f(int i)
    {
        // das ist mein 2ter Block ....     
        int x = 45; 
        return x;
    }
    
    int main()
    {
        // Main ist mein unterster block .... 
        int i = 4;
        i = f(i);
    }
    

    dein compiler compiliert das (hoffe ich mal) und legt binaercode dafuer an.
    Wird der binaercode vom Loader des BS geladen (in den Hauptspeicher, klar) ein prozess erzeugt, und bevor der Prozess mit dem einsprungpunkt(int main() ) gestartet wird , wird fuer das Programm vom BS noch mehrere Arten von Speicher reserviert. Der Grundlegenste ist der Stack .....

    Nun hat der Compiler deinen Code in binaere anweisungen gewandelt, und das erste was dein prog macht, befor es ueberhaupt anfaengt den code abzuarbeiten, ist den speicher fuer die Variablen in main zu reserverieren, und zwar auf den Stack ....

    In den oben genannten teil beispielsweise 4 Byte (und noch ne ganze menge mehr fuer andere sachen und variablen die du ned so siehst ) .....
    nun faengt der Prozess an zu arbeiten, und kommt zu dem funktionsaufruf f !

    fuer nen funktionsaufruf wird speicher fuer die argumente, der rueckgabewert und auch fuer die ruecksprungadresse benoetigt, diese werden an der stelle aufn Stack angelegt, und befuellt. .... bevor nun der prozess anfaengt f abzuarbeiten, wird noch der Speicher fuer die in f1 verwendeten variablen angelegt, das wird natuerlich auch auf den stack gemacht

    f wird abgearbeitet, wenn fertig, dann wird der speicher von den variablen fuer f wieder entfernt,
    danach die rueckgabewerte in main ubernommen und dancach auch der speicher fuer rueckabewert, argumente und der rueckabeadresse freigegeben ...

    danach gehts in main weiter, und wenn main fertig ist, werden die speicherberieche fuer dein main wieder vom stack freigegeben ...

    Dein compiler macht dafuer die meiste arbeit und baut den binaercode so, das es funktioniert ....
    er allociert den speicher natuerlich ned einzeln, sondern schoen blockweise .... und damit das funzt, musst der compiler natuerlich wissen, wieviel speicher er fuer deine Funktion / Programm anlegen muss. Deshalb gehen z.B. keine Arrays mit dynamischer groesse auf dem "Stack"

    Den Namen hat der Stack von seiner Arbeitsweise bekommen .... weil er dieser speicher ein "Stapel" behandlet wird, eintritt in main ... , erhoehe den Stackzeihger um das was mein braucht, und der speichermanager von mein bekommt die alte stackadresse und heut seine variablen dahin ....
    eintritt in f ... erhoehe den Stackzeiger um das was fuer f gebraucht wird, f bekommt den zeiger auf die alte adresse und legt seine variablen dahin ...
    Austritt aus f, der Stackzeiger wird um das was f gebraucht hat zurueckgesetzt ...

    etc ....

    Naja, so funzt das ansatzweise ... grob vereinfacht dargestellt ....

    WIssen muss man:
    Der STack ist dein grundlegender Speicher ...
    Der stack ist schnell, weil er keinen Speichermanager braucht ... sondern das zeugs per binaercode blockweise angwfordert wird, und in reihenfolge wieder freigegeben wenn nimmer gebraucht. Speicherluecken koennen theorethisch ned auftreten.
    Dein verbrauch an "Stackspeicher" muss demnach zur compilezeit bekannt sein"
    es gibt grenzen vom Stack die vom BS vorgegeben werden ....

    Ciao ...



  • Ich habe noch eine Frage zu den static Variablen und den globalen Variablen, wo werden diese gespeichert?

    Und der Code des Programms?

    Mein Prof. zählte diese Speicherbereiche auf: Betriebssystem, Stack, Heap, Codebereich, Datenbereich.

    Was ist mit dem Datenbereich, sind dort auch Variablen und außerdem hat er gesagt das die static Variablen im Codebereich liegen.

    Das ist jedenfalls das, was ich aus seinem Durcheinander erkennen konnte. 😞

    Ich danke für Infor mationen.

    mfg Mr.Schottky 😉



  • Mr.Schottky schrieb:

    Was ist mit dem Datenbereich, sind dort auch Variablen

    Logisch.

    Mr.Schottky schrieb:

    und außerdem hat er gesagt das die static Variablen im Codebereich liegen.

    Vermutlich eher nicht. Früher, zu DOS Zeiten, hat man mal sowas gemacht. Heutzutage gibt es dafür keinen Grund mehr.



  • Welche Variablen liegen dann im Datenbereich?

    Lokale?



  • Statische und globale.


Anmelden zum Antworten