it-swarm.com.de

Wo werden konstante Variablen in C gespeichert?

Ich frage mich, wo konstante Variablen gespeichert werden. Befindet es sich im selben Speicherbereich wie globale Variablen? Oder ist es auf dem Stapel?

41
hdn

Wie sie gespeichert werden, ist ein Implementierungsdetail (abhängig vom Compiler).

Beispielsweise werden im GCC-Compiler auf den meisten Maschinen schreibgeschützte Variablen, Konstanten und Sprungtabellen im Textabschnitt platziert.

40
Robert Harvey

Abhängig von der Datensegmentierung, der ein bestimmter Prozessor folgt, haben wir fünf Segmente:

  1. Codesegment - Speichert nur Code, ROM
  2. BSS (oder Block mit Symbol gestartet) Daten Segment - Speichert initialisierte globale und statische Variablen
  3. Stapelsegment - speichert alle lokalen Variablen und andere Informationen zur Funktionsrückgabeadresse usw
  4. Heap-Segment - hier finden alle dynamischen Zuordnungen statt
  5. Daten BSS (oder Block Started by Symbol) segment - speichert nicht initialisierte globale und statische Variablen

Beachten Sie, dass der Unterschied zwischen den Daten- und BSS-Segmenten darin besteht, dass in den ersten initialisierten globalen und statischen Variablen und in den späteren UN-initialisierten Variablen gespeichert werden.

Nun, warum spreche ich über die Datensegmentierung, wenn ich nur sagen muss, wo die konstanten Variablen gespeichert sind ... es gibt einen Grund dafür ...

Jedes Segment hat einen schreibgeschützten Bereich, in dem alle Konstanten gespeichert sind.

Zum Beispiel: 

  • Wenn ich ein const int habe, das eine lokale Variable ist, wird es im schreibgeschützten Bereich des Stapelsegments gespeichert.
  • Wenn ich ein globales const var habe, wird es im Datensegment gespeichert.
  • Wenn ich eine nicht initialisierte const var habe, dann wird sie im BSS-Segment gespeichert ...

Zusammenfassend ist "const" nur ein Daten-QUALIFIER. Dies bedeutet, dass der Compiler zuerst entscheiden muss, in welchem ​​Segment die Variable gespeichert werden soll. Wenn die Variable eine const ist, kann sie im schreibgeschützten Bereich von gespeichert werden das bestimmte Segment.

27
wrapperm

Betrachten Sie den Code:

const int i = 0;
static const int k = 99;

int function(void)
{
    const int j = 37;
    totherfunc(&j);
    totherfunc(&i);
  //totherfunc(&k);
    return(j+3);
}

Im Allgemeinen kann i im Textsegment gespeichert werden (es ist eine schreibgeschützte Variable mit einem festen Wert). Wenn es sich nicht im Textsegment befindet, wird es neben den globalen Variablen gespeichert. Da es auf null initialisiert ist, kann es sich im Abschnitt "bss" (wo normalerweise nullzählbare Variablen zugewiesen werden) oder im Abschnitt "data" (in dem normalerweise initialisierte Variablen zugewiesen werden) befinden.

Wenn der Compiler überzeugt ist, dass die Variable k nicht verwendet wird (was möglicherweise der Fall ist, dass sie lokal für eine einzelne Datei ist), erscheint sie möglicherweise überhaupt nicht im Objektcode. Wenn der Aufruf von totherfunc(), auf den k verweist, nicht auskommentiert wurde, müsste k irgendwo eine Adresse zugewiesen werden - sie würde sich wahrscheinlich im selben Segment wie i befinden.

Die Konstante (wenn es eine Konstante ist, ist sie immer noch eine Variable?) j wird höchstwahrscheinlich auf dem Stack einer herkömmlichen C-Implementierung angezeigt. (Wenn Sie in der Newsgruppe comp.std.c nachfragen, würde jemand sagen, dass der Standard nicht sagt, dass automatische Variablen auf dem Stack erscheinen; glücklicherweise ist SO nicht comp.std.c!)

Beachten Sie, dass ich die Variablen erzwungen habe, weil ich sie als Referenz übergeben habe - vermutlich an eine Funktion, die einen Zeiger auf eine konstante Ganzzahl erwartet. Wenn die Adressen niemals belegt wurden, könnten j und k aus dem Code heraus insgesamt optimiert werden. Um i zu entfernen, müsste der Compiler den gesamten Quellcode des gesamten Programms kennen - er ist in anderen Übersetzungseinheiten (Quelldateien) zugänglich und kann daher nicht ohne weiteres entfernt werden. Doppelt nicht, wenn das Programm das dynamische Laden gemeinsam genutzter Bibliotheken nachgibt - eine dieser Bibliotheken kann sich auf diese globale Variable verlassen.

(Stilistisch sollten die Variablen i und j längere und aussagekräftigere Namen haben; dies ist nur ein Beispiel!)

11

Abhängig von Ihrem Compiler, Ihren Systemfunktionen und Ihrer Konfiguration während des Kompilierens.

gccsetzt read-only-Konstanten in den .text-Abschnitt, sofern nicht anders angegeben.

4

natürlich nicht, weil 

1) Im bss-Segment wurden nicht inilisierte Variablen gespeichert, offensichtlich ist ein anderer Typ vorhanden.

       (I) large static and global and non constants and non initilaized variables it stored .BSS section.

       (II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.

2) Datensegment ist initialisierte Variablen, es gibt 3 Typen,

      (I) large static and global and initlaized and non constants variables its stord in .DATA section.
      (II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
     (III) small static and global and  constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.

ich erwähne oben kleine und große Mittel abhängig von Komplement, zum Beispiel kleine Mittel <8 Bytes und große Mittel> 8 Bytes und gleiche Werte.

aber mein zweifel ist örtlich konstant wo es stroe wird ??????

2
mohan

Normalerweise werden sie im schreibgeschützten Datenbereich gespeichert (während der Abschnitt für globale Variablen über Schreibberechtigungen verfügt). Wenn Sie also versuchen, die Konstante über die Adresse zu ändern, kann dies zu einer Zugriffsverletzung führen, die auch Segfault genannt wird.

Aber es hängt wirklich von Ihrer Hardware, Ihrem Betriebssystem und Ihrem Compiler ab.

1
elder_george

Dies ist meistens eine fundierte Vermutung, aber ich würde sagen, dass Konstanten normalerweise in den eigentlichen CPU-Anweisungen Ihres kompilierten Programms als unmittelbare Daten gespeichert werden. Mit anderen Worten, die meisten Anweisungen enthalten Platz für die Adresse, von der Daten abgerufen werden sollen. Wenn es sich jedoch um eine Konstante handelt, kann der Platz den Wert selbst enthalten.

1
Lee B

So wie ein Add-On, da Sie wissen, dass während des Verknüpfungsprozesses das Speicherlayout der endgültigen ausführbaren Datei festgelegt wird. Es gibt einen weiteren Abschnitt namens COMMON, in dem die gemeinsamen Symbole aus verschiedenen Eingabedateien platziert werden unter dem Abschnitt .bss.

0
achoora

Es muss im Textsegment gespeichert werden, da es sich um schreibgeschützte Variablen handelt. http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html

0
Shirley V

Global und Konstante sind zwei vollständig getrennte Schlüsselwörter. Sie können den einen oder den anderen, keinen oder beide haben.

Wo Ihre Variable gespeichert wird, hängt von der Konfiguration ab. Lesen Sie sich ein wenig über den Heap und den Stack durch, der Ihnen einiges Wissen vermittelt, um weitere (und wenn ich kann, bessere und spezifischere) Fragen zu stellen. 

0
Mizipzor

Ich habe das x86_64 GNU/Linux-System überprüft. Mit dem Zeiger auf die Variable 'const' kann der Wert geändert werden. Ich habe objdump benutzt. Die Variable 'const' wurde im Textsegment nicht gefunden. Die Variable 'const' wird im Stack gespeichert. 'const' ist eine Compiler-Direktive in "C". Der Compiler löst einen Fehler aus, wenn er auf eine Anweisung stößt, die die 'const'-Variable ändert.

0
Gangadhar

Einige Konstanten werden nicht einmal gespeichert.

Betrachten Sie den folgenden Code: int x = foo(); x *= 2;. Die Wahrscheinlichkeit ist groß, dass der Compiler die Multiplikation in x = x+x; umwandelt, da dadurch die Zahl 2 nicht mehr aus dem Speicher geladen werden muss.

0
MSalters

Es kann überhaupt nicht gespeichert werden.

Betrachten Sie einen Code wie diesen:

#import<math.h>//import PI
double toRadian(int degree){
  return degree*PI*2/360.0;
}

Auf diese Weise kann der Programmierer die Vorstellung von den Vorgängen sammeln, der Compiler kann jedoch einige davon optimieren, was die meisten Compiler tun, indem er konstante Ausdrücke zur Kompilierzeit auswertet. Dies bedeutet, dass der Wert PI möglicherweise nicht im resultierenden Programm enthalten ist überhaupt. 

0
tomjen