20 Stimmen

Wo werden Variablen in C++ gespeichert?

Wo werden Variablen in C++ gespeichert?

Im RAM oder im Cache des Prozessors?

0 Stimmen

Diese Frage macht keinen Sinn, da (die meisten) Caches transparent sind und eigentlich nur ein Teil des Speichersystems sind. Sie ist auch deshalb fehlerhaft, weil es wirklich von der Architektur und dem Compiler abhängt, wo die Variablen von C++ (oder jeder anderen kompilierten Sprache) gespeichert werden.

0 Stimmen

Auch der Titel der Frage könnte deutlich verbessert werden

1 Stimmen

@Tal, wie andere schon sagten, ist die Frage wie gesagt etwas vage. Vielleicht sollten Sie sich die Kommentare der Leute ansehen und sehen, ob Sie eine etwas spezifischere Frage stellen können.

46voto

Dan Lenski Punkte 72055

Benannte Variablen werden gespeichert:

  • Auf dem Stack, wenn es sich um funktionslokale Variablen handelt.
    C++ nennt dies "automatische Speicherung". 1 und erfordert nicht, dass es tatsächlich der asm-Aufrufstapel ist, und in einigen seltenen Implementierungen ist er es nicht. Aber in Mainstream-Implementierungen ist er es.
  • in einem prozessbezogenen Datenbereich, wenn sie global sind oder static .
    C++ nennt dies "statische Speicherklasse"; sie wird in asm implementiert, indem Bytes in section .data , .bss , .rodata oder ähnlich.

Wenn die Variable ein Zeiger ist, der mit int *p = new int[10]; oder ähnlich, die Zeigervariable p werden wie oben beschrieben automatisch oder statisch gespeichert. Die zeigt auf Objekt im Speicher ist:

  • Auf dem Heap (in C++ als dynamischer Speicher bezeichnet), zugewiesen mit new o malloc , usw.
    In asm bedeutet dies, eine Allokationsfunktion aufzurufen, die letztendlich neuen Speicher vom Betriebssystem über eine Art Systemaufruf erhält, wenn ihre Free-List leer ist. Der "Heap" ist in modernen Betriebssystemen/C++-Implementierungen kein einzelner zusammenhängender Bereich.

In C und C++ gibt es keine automatische Garbage Collection, und benannte Variablen können sich nicht selbst im dynamischen Speicher ("dem Heap") befinden. Objekte im dynamischen Speicher sind anonym, abgesehen davon, dass auf sie von anderen Objekten verwiesen wird, von denen einige echte Variablen sein können. (Ein Objekt vom Typ struct oder class, im Gegensatz zu primitiven Typen wie int können Sie in diesem anonymen Objekt auf benannte Klassenmitglieder verweisen. In einer Memberfunktion sehen sie sogar identisch aus).

Aus diesem Grund können Sie nicht (sicher/nützlich) einen Zeiger oder Verweis auf eine lokale Variable zurückgeben.


Das ist natürlich alles in RAM . Die Zwischenspeicherung ist für Benutzerraumprozesse transparent, obwohl sie die Leistung sichtbar beeinträchtigen kann.

Compiler können den Code so optimieren, dass Variablen in Registern gespeichert werden. Dies ist in hohem Maße compiler- und codeabhängig, aber gute Compiler werden dies aggressiv tun.


Fußnote 1: Spaßfakt: auto in C++03 und früher, und immer noch in C, bedeutete automatische Speicherklasse aber jetzt (C++11) werden daraus Typen abgeleitet.

8 Stimmen

Eigentlich werden Variablen nicht im Heap gespeichert. Sie können eine Variable haben, die auf etwas im Heap zeigt, aber die Variable selbst befindet sich in einem Register, auf einem Stack oder wird statisch zugewiesen.

0 Stimmen

Kristopher, ein gutes Argument. In der C++-Definition ist die Variable der Zeiger, nicht das Array, auf das der Zeiger zeigt, Sie haben also Recht.

0 Stimmen

Beachten Sie, dass die Speicherung von Variablen in Registern auch stark plattformabhängig ist. Verschiedene Architekturen haben eine unterschiedliche Anzahl von Registern, und nicht alle Register sind auf allen Architekturen gleich.

19voto

T.E.D. Punkte 42630

Für C++ im Allgemeinen lautet die richtige Antwort "wo auch immer Ihr Compiler sie hinstellt". Sie sollten keine anderen Annahmen treffen, es sei denn, Sie weisen Ihren Compiler in irgendeiner Weise an, etwas anderes zu tun. Einige Variablen können vollständig in Registern gespeichert werden, und einige können vollständig optimiert und irgendwo durch ein Literal ersetzt werden. Bei einigen Compilern auf einigen Plattformen können Konstanten tatsächlich im ROM landen.

Der Teil Ihrer Frage über "den Cache des Prozessors" ist etwas verwirrend. Es gibt einige Werkzeuge, mit denen man steuern kann, wie der Prozessor mit seinem Cache umgeht, aber im Allgemeinen ist das die Sache des Prozessors und sollte für Sie unsichtbar sein. Sie können sich den Cache als das Fenster Ihrer CPU zum Arbeitsspeicher vorstellen. Ziemlich genau jede Der Speicherzugriff erfolgt über den Cache.

Auf der anderen Seite wird ungenutzter Arbeitsspeicher bei den meisten Betriebssystemen auf die Festplatte ausgelagert. Es ist also möglich (aber unwahrscheinlich), dass Ihre Variablen zu bestimmten Zeitpunkten tatsächlich auf der Festplatte gespeichert werden :-)

1 Stimmen

Ich verstehe, dass der Compiler entscheiden kann, was er tun will. Gibt es Compiler, die derzeit etwas ganz anderes als das Übliche tun (automatic=stack oder registers, allocated=help usw.)?

1 Stimmen

@user231536: Für Architekturen wie PIC und 8051, bei denen es schwierig ist, den Call-Stack für das Standard-C-Modell zu verwenden, gibt es anscheinend einige Compiler, die Variablen der Speicherklasse automatisch in den statischen Speicher legen. (Und man muss Funktionen speziell als reentrant deklarieren, wenn man das will.) Supercat kommentierte dies in Warum erzeugen C-zu-Z80-Compiler schlechten Code? Diese Frage und Antwort ist im Allgemeinen voll von Beispielen für C, die sich nicht so einfach auf asm abbilden lassen (und einige asm, die einfach nur schlecht sind im Vergleich zu dem, was ein moderner optimierender Compiler tun könnte).

16voto

Mecki Punkte 113876

Variablen werden normalerweise im RAM gespeichert. Dies geschieht entweder auf dem Heap (z.B. globale Variablen, statische Variablen in Methoden/Funktionen) oder auf dem Stack (z.B. nicht-statische Variablen, die innerhalb einer Methode/Funktion deklariert werden). Stack und Heap sind beide RAM, nur an unterschiedlichen Orten.

Zeiger sind etwas Besonderes. Zeiger selbst folgen den oben genannten Regeln, aber die Daten, auf die sie zeigen, werden normalerweise auf dem Heap gespeichert (Speicherblöcke, die mit malloc Objekte, die mit new ). Sie können jedoch Zeiger erstellen, die auf den Stapelspeicher zeigen: int a = 10; int * b = &a; ; b verweist auf den Speicher von a y a wird auf dem Stapel gespeichert.

Was in den CPU-Cache geht, liegt außerhalb der Kontrolle des Compilers. Die CPU entscheidet selbst, was sie zwischenspeichert und wie lange sie es zwischenspeichert (abhängig von Faktoren wie " Wurden diese Daten kürzlich verwendet? " oder " Ist zu erwarten, dass die Daten schon bald wieder verwendet werden? ") und natürlich hat auch die Größe des Caches einen großen Einfluss.

Der Compiler kann nur entscheiden, welche Daten in ein CPU-Register gehen. Normalerweise werden Daten dort gespeichert, wenn sehr oft hintereinander auf sie zugegriffen wird, da der Registerzugriff schneller ist als der Cache und viel schneller als RAM. Einige Operationen können auf bestimmten Systemen nur ausgeführt werden, wenn sich die Daten in einem Register befinden. In diesem Fall muss der Compiler die Daten in ein Register verschieben, bevor er die Operation ausführt, und kann nur entscheiden, wann die Daten wieder in den RAM verschoben werden.

Die Compiler werden immer versuchen, die Daten, auf die am häufigsten zugegriffen wird, in einem Register zu halten. Wenn eine Methode/Funktion aufgerufen wird, werden normalerweise alle Registerwerte in den Arbeitsspeicher zurückgeschrieben, es sei denn, der Compiler kann mit Sicherheit sagen, dass die aufgerufene Funktion/Methode nicht auf den Speicher zugreifen wird, aus dem die Daten stammen. Auch bei der Rückkehr einer Methode/Funktion müssen alle Registerdaten in den Arbeitsspeicher zurückgeschrieben werden, da sonst die neuen Werte verloren gehen würden. Der Rückgabewert selbst wird bei einigen CPU-Architekturen in einem Register übergeben, ansonsten über den Stack.

8voto

Brian R. Bondy Punkte 325712

Variablen in C++ werden entweder auf dem Stack oder dem Heap gespeichert.

Stapel:

int x;

Haufen:

int *p = new int;

Allerdings handelt es sich bei beiden um Strukturen, die in den Arbeitsspeicher integriert sind.

Bei hoher RAM-Auslastung kann Windows diese auf die Festplatte auslagern.

Wenn Berechnungen mit Variablen durchgeführt werden, wird der Speicher in Register kopiert.

7voto

Drew Dormann Punkte 54591

C++ kennt den Cache Ihres Prozessors nicht.

Wenn Sie ein in C++ oder einer anderen Sprache geschriebenes Programm ausführen, speichert Ihre CPU eine Kopie "beliebter" Teile des Arbeitsspeichers in einem Cache. Das geschieht auf der Hardware-Ebene.

Betrachten Sie den CPU-Cache nicht als "anderen" oder "mehr" Speicher... er ist nur ein Mechanismus, um einige RAM-Blöcke in der Nähe zu halten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X