Globale Variablen, die keine expliziten Initialisierer erhalten, wie in diesem Fall Ihre, werden standardmäßig auf 0 initialisiert. Sie werden in einen Speicherbereich mit der Bezeichnung .bss segment gestellt, und in der Objektdatei/ausführbaren Datei werden keine zusätzlichen Daten gespeichert, die den Anfangswert der Daten angeben (im Gegensatz zu explizit initialisierten Daten, deren Anfangswert irgendwo gespeichert werden muss).
Wenn das Betriebssystem das Programm lädt, liest es die Beschreibungen aller Segmente ein und weist Speicher dafür zu. Da es weiß, dass das .bss-Segment für alle Nullen initialisiert wird, kann es einen hinterhältigen Trick machen, um zu vermeiden, dass tatsächlich Tonnen von Speicher zugewiesen und dann für alle Nullen initialisiert werden müssen: Adressraum für das Segment auf der Prozessseite Tabelle, aber alle Seiten zeigen auf die gleiche Seite, gefüllt mit Nullen.
Diese einzelne Nullseite ist ebenfalls schreibgeschützt. Wenn dann und wenn der Prozess in einige Daten in dem BSS-Segment schreibt, tritt ein Seitenfehler auf. Das Betriebssystem fängt den Seitenfehler ab, ermittelt, was passiert, und weist dann tatsächlich einen eindeutigen Speicher für diese Datenseite zu. Dann startet es den Befehl neu, und der Code fährt auf seinem fröhlichen Weg fort, als ob der Speicher die ganze Zeit zugewiesen worden wäre.
Also, das Endergebnis ist, dass, wenn Sie eine globale Variable oder Array mit Null initialisiert haben, jeder Seitengröße Daten (in der Regel 4 KB), nie geschrieben wird nie tatsächlich Speicher für sie zugewiesen haben.
Hinweis: Ich bin ein wenig verschwommen hier mit dem Wort "zugewiesen". Wenn Sie sich mit so etwas beschäftigen, werden Sie wahrscheinlich Wörter wie "reserviert" und "engagiert" finden. Weitere Informationen zu diesen Begriffen im Kontext von Windows finden Sie unter this question und this page.
Ich bezweifle, dass dies relevant ist, da es ein statisches Array ist, aber haben Sie versucht, das gesamte Array auf Null zu setzen? – Mysticial
Eigentlich ist das völlig relevant.Mit 'memset' ging das Programm von 92K auf 381.6M über. –
In diesem Fall ist die Antwort von templatetypedef korrekt. – Mysticial