Variablen



  • Hallo,

    wenn du eine Varibale deklarierst wird gar kein Speicher angelegt.
    Erst wenn du sie definierst wird dein int x; auf dem Stack angelegt, dass passiert wenn du die Variable initialisierst.
    Der Stack kann je nach Zustand deines Programmes im BS, im Arbeitssspeicher oder auf der Festplatte liegen. Braucht dich aber nicht interessieren.



  • wenn du eine Varibale deklarierst wird gar kein Speicher angelegt

    aber wenn ich doch cout<<x mache dann gibt er doch einen rubbish wert aus.

    Woher soll der kommen , wenn nicht aus dem Speicher ? außerdem
    kann man sich ja mit &x die Speicheradresse von x ausgeben lassen.



  • Wenn du nur eine Variable initialisiert, zeigt dessen Zeiger auf einen zufälligen Speicherbereich. Dementsprechend kommt der Wert dabei raus...



  • Richtig, dies passiert dann nach der Definition. Für globale Variablen wird das vor main gemacht und nach main wieder weg geräumt. Mit lokalen Variablen sieht es etwas anders aus, die werden wahrscheinlich erst an Ort und Stelle erzeugt.
    Du solltest dir mal den Unterschied von Deklaration/Definition ansehen, dann dürfte es auch etwas klarer werden.



  • int main()
    {
       int x;
    }
    

    Hier wird x sowohl deklariert als auch definiert. Es wird Speicher für x reserviert, sobald das Programm beim Ausführen an der Instruktion ankommt. An Fällen, wo eine reine Deklaration (also ohne Definition) von eingebauten Datentypen vorkommt, fällt mir auf Anhieb nur die Deklaration eines Bezeichners ein, dessen Definition in einer anderen Quelltextdatei stattfindet.



  • Belli schrieb:

    Es wird Speicher für x reserviert, sobald das Programm beim Ausführen an der Instruktion ankommt.

    Nicht unbedingt. Normalerweise wird für alle lokalen Variablen einer Funktion der Speicher reserviert, sobald die Ausführung der Funktion begonnen wird.

    An Fällen, wo eine reine Deklaration (also ohne Definition) von eingebauten Datentypen vorkommt, fällt mir auf Anhieb nur die Deklaration eines Bezeichners ein, dessen Definition in einer anderen Quelltextdatei stattfindet.

    Schlüsselwort extern sorgt für eine Deklaration ohne Definition. Des Weiteren sind statische Membervariablen einer Klasse erstmal nur deklariert und müssen getrennt davon definiert werden (Ausnahme: Integrale statische Member können sofort definiert werden).



  • pumuckl schrieb:

    Nicht unbedingt. Normalerweise wird für alle lokalen Variablen einer Funktion der Speicher reserviert, sobald die Ausführung der Funktion begonnen wird.

    Das überrascht mich ...
    Ich war felsenfest davon überzeugt, daß bei:

    void func()
    {
       viele Instruktionen ...
    
       if(bedingung)
           return;
    
       int x;
    
       noch mehr Instruktionen ...
    }
    

    x zum Beispiel nur für !bedingung angelegt wird ...



  • Belli schrieb:

    pumuckl schrieb:

    Nicht unbedingt. Normalerweise wird für alle lokalen Variablen einer Funktion der Speicher reserviert, sobald die Ausführung der Funktion begonnen wird.

    Das überrascht mich ...
    Ich war felsenfest davon überzeugt, daß bei:

    void func()
    {
       viele Instruktionen ...
    
       if(bedingung)
           return;
     
       int x;
    
       noch mehr Instruktionen ...
    }
    

    x zum Beispiel nur für !bedingung angelegt wird ...

    ja - mit optimierungen sollte das wohl so sein - nat nur, wenn es sich lohnt (die konstruktion der variable aufwendig genug ist und/oder das objekt relativ groß ist)

    bb



  • unskilled schrieb:

    nat nur, wenn es sich lohnt (die konstruktion der variable aufwendig genug ist und/oder das objekt relativ groß ist)

    Konstruktion != Speicherreservierung. Ein Speicheranfordern auf dem Stack dürfte eigentlich vertretbar sein.

    pumuckl schrieb:

    (Ausnahme: Integrale statische Member können sofort definiert werden).

    Du meinst wohl integrale statische konstante Member. 😉



  • Üblicherweise wird beim Aufruf einer Funktion ein Stackframe erzeugt und beim Verlassen wieder freigegeben, wobei das nur durch Verschieben eines Stack-Ende-Pointers geschieht. D.h. schonmal, dass "add stackpointer, 4" und "add stackpointer, 1234" keinen Laufzeitunterschied macht.

    Da der Compiler weiß, wieviel Speicher die Variablen der Funktion auf dem Stack benötigen, kann er Konstanten für die Menge nötigen Speicherplatzes einsetzen. D.h. widerum, dass jede weitere Allokation im Verlauf der Funktion eine weitere Anweisung bedeuten würde, ein Erhöhen der Anzahl am Anfang der Funktion jedoch nicht.

    Das ist die übliche Vorgehensweise, zumindest auf x86 Maschinen, weshalb Allokation auf dem Stack auch sehr schnell ist und nicht von der Menge des benötigten Platzes abhängt. Konstruktion ist dann wieder eine andere Geschichte.



  • Das bedeutet also, daß bei:

    void func(bool wahr)
    {
       if(wahr)
       {
          char c = 'A';
          std::cout << c;
       }
       else
       {
          double d = 1.0;
          std::cout << d;
       }
    }
    

    immer gleich viel Speicher auf dem Stack, nämlich für c und für d, reserviert wird?



  • Für wahr, c und d, ja.


Anmelden zum Antworten