Warum werden globale Variablen immer auf ‘0’ initialisiert, aber nicht lokale Variablen? [duplicate]

Lesezeit: 4 Minuten

Benutzeravatar von yuvanesh
Yuvanesh

Mögliches Duplikat:

Warum werden globale und statische Variablen auf ihre Standardwerte initialisiert?

Siehe Code,

#include <stdio.h>

int a;
int main(void)
{
    int i;
    printf("%d %d\n", a, i);
}

Ausgabe

0 8683508

Hier wird ‘a’ mit ‘0’ initialisiert, aber ‘i’ wird mit einem ‘Junk-Wert’ initialisiert. Wieso den?

  • Geschlossen, aber der offensichtlichste Grund wird nicht erwähnt: Lokale Variablen sind nur Zeiger auf den Stack, und der Stack ändert sich ständig.

    – dagelf

    6. November 2020 um 11:38 Uhr

Benutzeravatar von K-ballo
K-ballo

Denn so ist es laut C-Standard. Der Grund dafür ist Effizienz:

  • statisch Variablen werden bei initialisiert Kompilierzeit, da ihre Adresse bekannt und fest ist. Initialisieren sie auf 0 fallen keine Laufzeitkosten an.

  • automatisch Variablen können für verschiedene Aufrufe unterschiedliche Adressen haben und müssten bei initialisiert werden Laufzeit Jedes Mal, wenn die Funktion aufgerufen wird, entstehen Laufzeitkosten, die möglicherweise nicht benötigt werden. Wenn Sie diese Initialisierung benötigen, fordern Sie sie an.

  • nette Antwort +1, … globale Werte werden zugewiesen 0 zur kompilierungszeit na?

    – Grijesh Chauhan

    27. Dezember 2012 um 5:45 Uhr

  • Wenn die globalen Variablen nicht auf einen Wert ungleich Null initialisiert werden, werden sie beim Laden des Prozessabbilds vor dem auf Null gesetzt main Programm startet. Das ist eine einmalige Operation, verglichen mit einer Operation „bei jedem Aufruf der Funktion“ für lokale Variablen.

    – Jonathan Leffler

    27. Dezember 2012 um 7:03 Uhr

  • tatsächlich werden auch statische Variablen zur Laufzeit initialisiert. Die C-Laufzeitumgebung (crt) initialisiert sie, bevor sie main aufruft. Das passiert natürlich nur einmal, aber immer noch zur Laufzeit.

    – Sil

    9. Oktober 2013 um 13:46 Uhr

  • Außerdem können Sie zur Kompilierzeit nichts initialisieren. Das Programm muss gestartet und in den Speicher geladen werden, damit Sie den Inhalt (in diesem Fall den bss-Abschnitt) löschen können. Das ist zur Kompilierzeit nicht möglich, nur zur Laufzeit. Prost

    – Sil

    9. Oktober 2013 um 13:48 Uhr

  • @Sil – von den Fällen, die ich untersucht habe, haben Sie in Ihrem 1. Kommentar Recht. Können Sie jedoch den 2. rechtfertigen? Da die Variablenzuordnung zur Ladezeit bekannt ist, warum ist es Ihrer Meinung nach nicht möglich, die Initialisierungswerte in das Binärbild einzufügen und die Variablen während des Ladens des Bildes festzulegen?

    – jap

    18. November 2014 um 19:08 Uhr

Benutzeravatar von Raghu Srikanth Reddy
Raghu Srikanth Reddy

global und static Variablen werden im Datensegment (DS) gespeichert, wenn sie initialisiert sind, und Blockstart durch Symbol (BSS), wenn sie nicht initialisiert sind.

Diese Variablen haben einen festen Speicherort, und der Speicher wird zur Kompilierzeit zugewiesen.

Daher global und static Variablen haben '0' als ihre Standardwerte.

Wohingegen auto Variablen werden auf dem Stapel gespeichert und haben keinen festen Speicherort.

Speicher wird zugeordnet auto Variablen zur Laufzeit, aber nicht zur Kompilierzeit. Somit auto Variablen haben ihren Standardwert als Garbage.

  • Das ist nicht ganz richtig. .bss wird während der Kompilierzeit nicht zugewiesen, und das ist eigentlich der Grund für die Einführung von .bss als speziellem Abschnitt für nicht initialisierte/null statische/globale Variablen. Es müssen nur Größeninformationen gespeichert werden, und daher wird die Binärdatei nicht mit unnötigen Daten (z. B. Nullen) verwüstet. Zur Laufzeit werden .bss-Variablen mit Null initialisiert (im Gegensatz zu Variablen im Abschnitt .data, wo der eigentliche Anfangswert hat innerhalb der Binärdatei gespeichert werden). Außerdem halte ich dies für die bessere Antwort, +1 🙂

    – andree

    18. Dezember 2015 um 21:03 Uhr

Benutzeravatar von Jonathan Leffler
Jonathan Leffler

Sie haben einfache Variablen ausgewählt, aber bedenken Sie:

void matrix_manipulation(void)
{
    int matrix1[100][100];
    int matrix2[100][100];
    int matrix3[100][100];

    /* code to read values for matrix1 from a file */
    /* code to read values for matrix2 from a file */
    /* code to multiply matrix1 by matrix2 storing the result in matrix3 */
    /* code to use matrix3 somehow */
}

Wenn das System die Arrays auf 0 initialisiert, wäre der Aufwand verschwendet; die Initialisierung wird durch den Rest der Funktion überschrieben. C vermeidet nach Möglichkeit versteckte Kosten.

  • Die Mühe wäre verschwendet, wenn sie auch einfache Variablen wären …

    – K-ballo

    27. Dezember 2012 um 5:41 Uhr

  • @K-ballo: Ja, du hast Recht – aber die Kosten sind deutlicher, wenn die Variablen große Arrays oder Strukturen oder Arrays von Strukturen sind. Selbst ein paar Dutzend Integer-Variablen, die initialisiert werden, sind nicht sehr auffällig, aber ein paar tausend Integer-Werte machen sich bemerkbar.

    – Jonathan Leffler

    27. Dezember 2012 um 5:45 Uhr

  • Sogar 1 Integer ist wahrnehmbar (+1 Anweisung), wenn sie sich in einer inneren Schleife von etwas befindet, das nur 4 Anweisungen zur Ausführung verwendet.

    – Erik Aronesty

    28. November 2014 um 14:53 Uhr

Benutzeravatar von WiSaGaN
WiSaGaN

Globale Variablen werden vor dem zugewiesen und initialisiert main -Funktion gestartet, während lokale Variablen auf dem Stack generiert werden, während die Instanz des Programms ausgeführt wird.

1412780cookie-checkWarum werden globale Variablen immer auf ‘0’ initialisiert, aber nicht lokale Variablen? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy