2010-06-20 8 views
10

Ich weiß, dass es Abschnitte wie Stack, Heap, Code und Daten gibt. Stack/Heap verwenden sie denselben Speicherbereich wie sie unabhängig voneinander wachsen können? Was ist dieser Codeabschnitt? Wenn ich eine Funktion habe, ist das ein Teil des Stacks oder der Code-Sektion? Was ist dieses initialisierte/nicht initialisierte Datensegment?Wie ist das Speicherlayout eines C/C++ Programms?

Gibt es einen schreibgeschützten Speicherbereich? Wenn ich eine const-Variable habe, ist es tatsächlich so, dass der Compiler einen Speicherbereich als schreibgeschützt markiert oder ihn in einen schreibgeschützten Speicherbereich legt.

Wo werden statische Daten gespeichert? Wo werden globale Daten gespeichert?

Alle guten Referenzen/Artikel für die gleichen?

Ich dachte, die Speicherbereiche und das Layout sind OS-unabhängig und es hat mehr mit Compiler zu tun. Nicht Stack, Heap, Code, Daten [initialisiert, nicht initialisiert] Segment in allen Betriebssystemen auftreten? Wenn es statische Daten gibt, was passiert, hat der Compiler verstanden, dass es statisch ist, was als nächstes, was wird es tun? Es ist der Compiler, der das Programm verwaltet und es sollte wissen, was zu tun ist, richtig? Alle Compiler sollten nicht gemeinsame Standards befolgen?

+1

+1 für die Neugier und den Enthusiasmus - aber Sie würden erheblich die Chancen verbessern, konkrete Antworten zu bekommen, wenn Sie es in einzelne Fragen aufteilen würden. –

+1

Es wäre einfacher, Ihre Frage zu beantworten, wenn wir verstanden haben, warum Sie wissen wollen und (weil es sehr plattform-/kompilerspezifisch ist), auf welche Plattform Sie abzielen. Obwohl die Antwort auf diese Fragen nicht allgemeingültig für einen allgemeinen C++ - Programmierer ist (mit Ausnahmen wie Compiler-/Gerätetreiber-Autoren), ist die Lebensdauer eines Objekts und wie sich die verschiedenen Objekttypen auf die Lebensdauer auswirken, wichtiger. –

Antwort

3

Es ist meist abhängig vom Betriebssystem.

Für Windows werfen Sie einen Blick auf Petzold oder Richters Bücher. Für Linux können Sie die Quelle lesen!

+0

Die Quelle lesen? Das hört sich sehr nach RTFM an: p –

+0

Ich glaube, er braucht Hilfe beim Lesen des F'ing Memory;) – MSalters

+0

@Matthieu M Ich habe ein "!" ;-) –

3

AFAIK:

Stapel/Haufen tun sie den gleichen Abschnitt des Speichers verwenden da sie unabhängig wachsen können?

Sie können unabhängig voneinander wachsen.

Was ist dieser Codeabschnitt?

Ein schreibgeschütztes Segment, in dem Code- und const-Daten gespeichert sind.

Wenn ich eine Funktion habe, ist es ein Teil des Stapels oder der Codeabschnitt?

Die Definition (Code) der Funktion wird in der CS sein. Die Argumente jedes Aufrufs werden auf dem Stapel übergeben.

Auch was ist das initialisiert/nicht initialisierte Daten Segment?

Im Datensegment werden globale/statische Variablen gespeichert.

Gibt es einen schreibgeschützten Speicherbereich ?

Das Codesegment. Ich nehme an, dass einige Betriebssysteme möglicherweise Grundelemente zum Erstellen von benutzerdefinierten schreibgeschützten Segmenten bieten.

Wenn ich eine konstante Variable haben, was tatsächlich geschieht, ist es, dass der Compiler einen Speicher Abschnitt markiert als nur lesen oder nicht setzen es in einem Nur-Lese-Speicherabschnitt.

Es geht in die CS.

Wo werden statische Daten gespeichert? Wo werden globale Daten gespeichert?

Das Datensegment.

+0

Readonly-Segmente waren in frühen Windows-Versionen sehr beliebt. Sie können damit mehrere Kopien einer App ausführen, ohne viel Speicherplatz zu verbrauchen. Sogar die String-Ressourcen landeten in gemeinsamen Lese-Segmenten. –

6

Es gibt sehr wenig, das tatsächlich über C++ Speicherlayouts definitiv ist. Die meisten modernen Betriebssysteme verwenden jedoch ein etwas ähnliches System und die Segmente sind basierend auf Berechtigungen getrennt.

Code hat Ausführungsberechtigung. Die anderen Segmente nicht. In einer Windows-Anwendung können Sie nicht nur nativen Code auf den Stack setzen und ausführen. Linux bietet die gleiche Funktionalität - es ist in der x86-Architektur.

Daten sind Daten, die Teil des Ergebnisses (.exe, etc) sind, aber nicht geschrieben werden können. Dieser Abschnitt ist im Grunde, wo Literale gehen. Leseberechtigung nur in diesem Abschnitt.

Diese beiden Segmente sind Teil der resultierenden Datei. Stack und Heap sind Laufzeit zugeordnet, anstatt von der Festplatte zugeordnet.

Stack ist im Wesentlichen ein, groß (1MB oder so, viele Compiler bieten eine Einstellung dafür) Heap-Zuweisung. Der Compiler verwaltet es für Sie.

Heap-Speicher ist Speicher, den das Betriebssystem durch einen bestimmten Prozess an Sie zurückgibt. Normalerweise ist Heap ein Heap (die Datenstruktur) von Zeigern zu freien Speicherblöcken und deren Größen. Wenn Sie einen anfordern, wird es Ihnen gegeben. Beide lesen und schreiben Berechtigungen hier, aber keine Ausführung.

Es gibt einen Nur-Lese-Speicher (ROM). Dies ist jedoch nur der Abschnitt "Daten". Sie können es zur Laufzeit nicht ändern. Wenn Sie eine const-Variable erstellen, passiert nichts Besonderes im Speicher. Alles was passiert, ist, dass der Compiler nur bestimmte Anweisungen darauf erstellt. Das ist es. x86 hat keine Kenntnisse oder Vorstellung von Konstanten im Compiler.

+4

Viel von dem, was Sie geschrieben haben, z.B. "Stack ist im Wesentlichen eine große Heap-Zuweisung" oder "x86 hat keine Ahnung von" const "", ist sehr ungenau. Ich weiß es zu schätzen, dass Sie versuchen, dies zu erklären, ohne über die virtuelle Adressierung zu sprechen, aber der virtuelle Speicher ist wirklich der Schlüssel dafür, wie all dies funktioniert. Vor allem Seitentabellen, wo die Berechtigungen für jeden Abschnitt definiert sind. Und natürlich variiert das alles * signifikant * auf Nicht-x86-Prozessoren. –

+1

Ich bin mir der virtuellen Adressierung voll bewusst. Wie du gesagt hast, versuche ich es einfach zu halten. – Puppy

0

(Anmerkung: Die folgenden gilt für Linux)

Der Stapel und Heap eines Prozesses existieren sowohl in der „gleichen“ Teil eines Speichers des Prozesses. Der Stack und der Heap wachsen aufeinander zu (zunächst, wenn der Prozess gestartet wird, belegt der Stack die gesamte Fläche, die durch die Kombination aus Stack und Heap besetzt werden kann; jede Speicherzuweisung (malloc/free/new/delete) kann dies tun Schieben Sie die Grenze zwischen dem Stapel und dem Stapel entweder nach oben oder nach unten). Der BSS-Abschnitt, der sich ebenfalls auf demselben vom Betriebssystem zugewiesenen Prozessbereich befindet, befindet sich in einem eigenen Abschnitt und enthält globale Variablen. Schreibgeschützte Daten befinden sich im Rodata-Abschnitt und enthalten beispielsweise Zeichenfolgenliterale. Zum Beispiel, wenn Ihr Code die Zeile hat:

char tmpStr[] = "hello"; 

Dann wurde der Teil des Quellcodes mit „Hallo“ im Rodata Abschnitt befindet.

Ein gutes, gründliches Buch dazu ist Randall E. Bryants Computer Systems.

+1

Der Stapel belegt NICHT den gesamten Adressraum. Tatsächlich ist es ein Fehler, über den "Stack" zu sprechen, da jeder Thread seinen eigenen Stack hat und es möglicherweise zusätzliche Stacks für Signalbehandlung, Fehlerkorrektur usw. gibt. –

+0

Was ich damit beendete, war, dass der Stack den Stack belegt gesamter Adressraum, der von der Kombination aus Stack und Heap belegt werden kann. – jrupac

0

Ich war in demselben Dilemma, als ich über Speicherlayout von C/C++ las.Hier ist der Link, dem ich gefolgt bin, um die Fragen zu klären.

http://www.geeksforgeeks.org/memory-layout-of-c-program/

Die Haupt Darstellung der Verbindung wird hier hinzugefügt:

enter image description here

Ich hoffe, diese Antworten auf ähnliche Frage 'die eine' hilft zu finden.

+1

Das Veröffentlichen von Nur-Link-Antworten kann für zukünftige Benutzer von StackOverflow nutzlos werden, wenn die Verbindung nicht mehr funktioniert. Versuchen Sie, und fügen Sie die wichtigen Punkte des Links in die Antwort selbst ein –

+0

Danke für den Rat. Sicher zu folgen. Das war meine erste Antwort :-) –

Verwandte Themen