stack/heap



  • hi leute,

    also wenn ich das richtig verstanden habe wird das meiste auf
    den stack gepackt, was denk ich mal der cpu cache is,
    und heap grob der ram.

    gibts so ne grundregel was man lieber auf den stack packt und
    was auf den heap?

    hab ehrlich gesagt mit new,delete, malloc und was es da gibt noch nicht
    gearbeitet, aber denke das es wohl wichtig wird sich damit zu beschäftigen.

    danke schonmal im voraus



  • adonis schrieb:

    hi leute,

    also wenn ich das richtig verstanden habe wird das meiste auf
    den stack gepackt, was denk ich mal der cpu cache is,
    und heap grob der ram.

    gibts so ne grundregel was man lieber auf den stack packt und
    was auf den heap?

    hab ehrlich gesagt mit new,delete, malloc und was es da gibt noch nicht
    gearbeitet, aber denke das es wohl wichtig wird sich damit zu beschäftigen.

    danke schonmal im voraus

    Sowohl stack als auch heap befinden sich im arbeitsspeicher.

    Der stack wird als Notizblock der cpu bezeichnet.

    Der stack, der einem programm zugewiesen wird ist sehr kanpp (1 mb ???), deswegen sollte man, vor allem bei großen datenmengen den heap benutzen.

    malloc() (C) und new (C++) kann man für dynamische speicherverwaltung nutzen.

    Wenn du zB einen C array anlegst, so muss die arraygröße konstant sein:

    int array[14]; /* das geht */
    int array_size = 14;
    int array2[array_size]; /* das geht nicht = error*/
    
    int* parray = malloc(array_size*sizeof(int)); /* geht */
    


  • Hallo,

    Wichtig? Komm erstmal in die Datenbankerstellung 🙄.

    MFG winexec*



  • Der Stack funktioniert eben nach einfachem Stapel-Prinzip. Wenn man Daten speichern will, dann legt man es einfach oben drauf. Wenn die Daten ungültig werden, hebt man sie einfach von oben ab. Der Stack ist nicht sonderlich groß (die größe ist vom Betriebssystem und diversen Einstellungen abhängig)

    Der Heap dagegen arbeitet mit komplizierten Algorithmen und Tabellen, um die Speicheranforderungen sinnvoll zu verteilen. Dafür kann man aber Speicher jederzeit freigeben. Der Heap ist für große und langlebige Daten gedacht, während der Stack für lokale Variablen und ähnliches genutzt wird (weil hier das drauflegen/abheben am leichtesten funktioniert).

    Normale Variablen werden auf dem Stack angelegt. Mit new bzw. new[] kannst du Speicher auf dem Heap anfordern (den du aber mittels delete bzw. delete[] manuell freigeben musst!). (In C++ lohnt sich aber für die Speicherverwaltung Smart-Pointer einzusetzen.)

    void foo() {
      int a = 0; // variable auf dem Stack
    } // hier wird die Variable automatisch "zerstört"
    


  • stapelprinzip sagt mir noch was LIFO last in, first out.
    push ax
    push bx

    pop bx
    pop ax
    .......

    wie ist das eigendlich wenn man den speicher nicht wieder freigibt?
    bleibt der speicher weiterhin reserviert, auch wenn man das programm
    beendet? oder nur innerhalb der laufzeit des programms?



  • Moderne Betriebssysteme räumen sämtlichen, von deinem Programm verwendeten speicher auf. Es ist jedoch good practice, selbst aufzuräumen.

    Greetz, Swordfish



  • Das Problem mit der Speicherfreigabe besteht, bei langlaufender Software (wie zB Servern).

    Die meisten GUI und Serverprogramme dürften ja ungefähr so aussehen

    init();
    while(event()) {
      handle_event();
    }
    deinit();
    

    Wenn du nun nicht sauber deine Resourcen freigibst und bei handle_event zB jedes mal 100 byte Speicher nicht freigibt, kannst du dir ja ausrechnen wie viele events dein Programm verarbeiten kann, bis der Speicher vollgelaufen ist und irgend wann der Rechner lahm liegt.



  • ahh noch eine frage,

    also wenn ich ein object mit new erstelle, werden dann
    die ganzen variablen des objects auf den heap gepackt?

    zumindest würde ich mir das so vorstellen, da ich sonst kein
    sinn sähe ein object mit new zu erstellen.
    oder sehe ich da was falsch?

    fragen über fragen



  • also wenn ich das richtig verstanden habe, müsste alles
    so in der art aussehen?

    include <iostream>
    #include <cstring>
    
    #include "datenbank.h"
    
    void progstart();
    void optionen();
    using namespace std;
    
    void main(void)
    {
    	DatenBank* myBank = new DatenBank;
    	progstart();
    	optionen();
    	delete myBank;
    }
    
    void progstart()
    {
    	cout<<"*******************************************"<<endl;
    	cout<<"* Programm zur Erstellung einer Datenbank.*"<<endl;
    	cout<<"* vers. 1.0                               *"<<endl;
    	cout<<"*                                         *"<<endl;
    	cout<<"*******************************************"<<endl;
    	cout<<endl<<endl;
    }
    
    void optionen()
    {
    	int* auswahl = new int;
    	char* temp = new char;
    	cout<<"--------------------------"<<endl;
    	cout<<"1. Neues Projekt erstellen"<<endl;
    	cout<<"2. Altes Projekt laden    "<<endl;
    	cout<<"--------------------------"<<endl;
    	cin>>*auswahl;
    
    	switch(*auswahl)
    	{
    	case 1:
    		cout<<"Neues Projekt"<<endl;
    		cin>>*temp;
    		break;
    	case 2:
    		cout<<"Altes Projekt"<<endl;
    		cin>>*temp;
    		break;
    		delete auswahl;
    		delete temp;
    	}
    }
    


  • Nein, in deinem Fall hast du ja in optionen() eine Speicherlücke, wenn der Benutzer 1 wählt.

    Außerdem sollte dir bewusst sein, dass du mit

    char *temp=new char;
    

    exakt Speicher für ein char anlegst.

    Generell macht es aber in deinem Programm wenig Sinn Speicher auf dem Heap zu erzeugen. Besonders für einzelne Variablen vom Typ int oä. Außerdem ist void main falsch!



  • Dieser Thread wurde von Moderator/in kingruedi aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ok, also kleine variablen, die keinen grösseren sinn haben,
    wie variablen für switch/case oä, nicht mit new.
    nur welche wo grosse datenmengen wie zb nen int array 640*480
    wo ich nen ganzes bild unterbringen könnte.

    delete aus der option funktion, hab ich mal aus switch case rausgenommen.
    und hinter "}" gesetzt.

    optionen() speicherlücke, leuchtet mir noch nicht ganz ein.
    (*noch nen schluck kaffe nimmt und hofft, dass es hilft*)

    danke hab mir mal den link zu void main in die favs gepackt, hatte das nie
    verstanden,hatte es so aus nem buch gelernt, hab 2 grundlagenbücher, da steht auch immer void main.

    edit:

    aja und void main() hab ich natürlich geändert:)



  • adonis schrieb:

    void optionen()
    {
        int* auswahl = new int;
        char* temp = new char;
        cout<<"--------------------------"<<endl;
        cout<<"1. Neues Projekt erstellen"<<endl;
        cout<<"2. Altes Projekt laden    "<<endl;
        cout<<"--------------------------"<<endl;
        cin>>*auswahl;
    
        switch(*auswahl)
        {
        case 1:
            cout<<"Neues Projekt"<<endl;
            cin>>*temp;
            break;
        case 2:
            cout<<"Altes Projekt"<<endl;
            cin>>*temp;
            break;
            delete auswahl;
            delete temp;
        }
    }
    

    Variablen mit kurzer Lebensdauer werden i.d.R. auf dem Stack abgelegt. Du würdest doch nicht

    for( int *i = new int( 1 ); *i <= 10; ++(*i) )
        cout << *i << endl;
    delete i;
    

    schreiben, oder?

    Beachte, dass eine Reservierung von Speicher auf dem Heap im allgemeinen langsamer ist, als ein einfaches PUSH auf dem Stack.

    Greetz, Swordfish



  • ok, noch eine frage:)

    geh ich recht in der annahme dass für jedes programm ein stack
    angelegt wird?

    ich mein jedes programm hat variablen die auf den stack gelegt werden.
    bei einer bestimten anzahl von laufenden programmen, würde ein
    einzelner stack ja vollaufen.

    oder gibt es einen fest reservierten bereich von einer bestimmeten
    grösse, was der gesamt stack ist, wo jedes programm einen teil zugewiesen bekommt worin er arbeiten kann?



  • Jedes Programm (eigentlich jeder Thread) bekommt seinen eigenen Stack.

    Greetz, Swordfish



  • Gründe den Stack dem Heap vorzuziehen:

    1. Die Destruktion wird automatisch vorgenommen
    2. Automatischer Destruktoraufruf beim stack-unwinding von try-catch
    3. Es kann kein delete vergessen werden -> keine Speicherlöcher
    4. Es kann nicht fälschlicherweise delete statt delete[] nach "new char[]"
    verwendet werden, keine Speicherlöcher durch vergessene Klammern []
    (ohne [] löscht delete nur die erste Speicherstelle des char[]-Arrays)
    5. "string" hat im Gegensatz zu "new char[]" eine vollkommen dynamische Länge
    6. Stack-Variablen können vom Compiler optimaler genutzt werden (Addressierung mittels ebp)
    7. Heap-Management sollte man generell immer der STL überlassen

    mfg



  • ok, wenn ich das jetzt also richtig verstanden habe.
    der stack wird nur anders verwaltet, als der heap.
    der ganze ram könnte auch ein kompletter stack sein, wenn man ihn
    so definiert.

    was wo als stack definiert wird regelt das betriebssystem.
    für jedes programm wir ein bereich im ram als stack definiert.

    wie ich stack und heap nutze muss ich selber entscheiden.

    heap-management und stl werd ich mal nachschlagen.

    so, hoffe das ich das jetzt alles soweit richtig verstanden habe:)

    aber muss zugeben ziehmlich interessantes thema



  • adonis schrieb:

    .

    was wo als stack definiert wird regelt das betriebssystem.

    Stackgrösse ist Linker-Option /STACK:reserve[,commit]



  • könnte man ein programm schreiben wo der stack
    erst während der laufzeit vollläuft? würde gern mal sehen was
    dann passiert:)



  • adonis schrieb:

    könnte man ein programm schreiben wo der stack
    erst während der laufzeit vollläuft?

    Während der Compilezeit kann der Stack des Programms nicht vollaufen 😉

    void murks()
    {
        int ary[1000];
        murks();
    }
    
    int main()
    {
        murks();
    }
    

    Der Array wäre nichtmal nötig, allerdings geht's dann schneller 😃


Log in to reply