2010-12-04 8 views
3

Erhöht globale Variablen die Größe der ausführbaren Datei? Wenn ja wie? Erhöht es nur die Größe des Datenbereichs oder auch die Größe des Textbereichs?Wie tragen globale Variablen zur Größe der ausführbaren Datei bei?

Wenn ich eine globale Variable und Initialisierung haben wie folgt:

char g_glbarr[1024] = {"jhgdasdghaKJSDGksgJKASDGHKDGAJKsdghkajdgaDGKAjdghaJKSDGHAjksdghJKDG"}; 

Nun, das 1024-Datenbereich hinzufügt und die Größe des initilization Streichern in Text?

Wenn stattdessen, wenn ich Speicherplatz für dieses Array statisch zuweisen, wenn ich malloc es, und dann ein memcpy tun, wird nur die Größe des Datenbereichs reduziert oder die Größe des Textabschnitts wird auch reduzieren?

Antwort

5

Ja, tut es. Grundsätzlich speichern Compiler sie im Datensegment. Manchmal, wenn Sie ein konstantes Char-Array in Ihrem Code verwenden (wie printf("<1024 char array goes here");), wird es zum Datensegment gehen (AFAIK einige alte Compiler/Borland?/Kann es im Textsegment speichern). Sie können den Compiler zwingen, eine globale Variable in einen benutzerdefinierten Abschnitt zu setzen (für VC++ war es #pragma data_seg(<segment name>)).

Die dynamische Speicherzuweisung wirkt sich nicht auf Daten/Textsegmente aus, da sie Speicher im Heap zuweist.

2

Ich spreche nicht als Experte, aber ich würde vermuten, dass einfach das epische Stringliteral in Ihrem Programm die Größe Ihrer ausführbaren Datei erhöhen würde. Was Sie mit diesem String-Literal machen, spielt keine Rolle, denn es muss irgendwo gespeichert werden.

Warum ist es wichtig, welcher "Abschnitt" der ausführbaren Datei erhöht wird? Dies ist keine rhetorische Frage!

+1

Das String-Literal ** kann ** entfernt ** werden, wenn ** es nirgendwo tatsächlich verwendet wird. –

+0

Das String-Literal ist nur ein Beispiel. Es kann viele solcher globalen Variablen geben, die ein Array von Strukturen sein können und mit Strings, Ganzzahlen usw. initialisiert werden können. Wird das Zuweisen von Speicher für diese globalen Variablen mit Hilfe von malloc irgendeine Größe reduzieren? – Jay

+0

"Warum ist es wichtig, welcher" Abschnitt "der ausführbaren Datei erhöht wird?" - Es geht nur darum, ein tieferes Verständnis dafür zu bekommen, wie die Dinge funktionieren. – Jay

1

Die Antwort ist leicht Implementierung empfindlich, aber im Allgemeinen, nein. Ihr g_glbarr ist wirklich ein Zeiger auf char oder eine Adresse. Der String selbst wird mit konstanten Strings in den Datenbereich geschrieben und g_glbarr wird ein Symbol für die Adresse des Strings zum Zeitpunkt der Kompilierung. Sie ordnen nicht schließlich Speicherplatz für den Zeiger zu und der Compiler löst die Adresse einfach zu Verbindungszeit auf.

aktualisieren

@Jay, dann ist es sorta irgendwie gleich. Die Integer (normalerweise) sind nur In-line: Der Compiler wird so nah wie möglich kommen, um die Konstante in den Code zu setzen, denn das ist so ein gewöhnlicher Fall, dass die meisten normalen Architekturen einen direkten Weg aus unmittelbaren Daten haben. Die String-Konstanten befinden sich immer noch in einigen schreibgeschützten Datenbereichen. Also, wenn Sie so etwas wie machen:

// warning: I haven't compiled this and wouldn't normally 
// do it quite this way so I'm not positive this is 
// completely grammatical C 
struct X {int a; char * b; } x = { 1, "Hello" } ; 

die 1 wird „sofort“ Daten werden die "Hello" irgendwo im schreibgeschützten Daten zugeordnet ist, und der Compiler wird nur etwas erzeugen, die ein Stück Lese-Schreib-Daten zuordnet, dass so etwas wie

x: 
x.a: WORD 1 
x.b WORD @STR42 

sieht, wo STR42 für den Standort des Strings "Hello" im Speicher ein symbolischer Name ist. Wenn dann alles miteinander verknüpft ist, wird die @STR42 durch die tatsächliche virtuelle Adresse der Zeichenfolge im Speicher ersetzt.

+0

danke für die Antwort. Aber was passiert, wenn ich ein Array von Strukturen benutze und es mit ganzen Zahlen und Strings initialisiere. Funktioniert das auch auf die gleiche Weise? – Jay

3

Die Antwort ist abhängig von der Implementierung, aber für vernünftige Implementierungen dies ist, wie es für Variablen mit statischer Speicherdauer arbeitet (global oder auf andere Weise):

  • Jedes Mal, wenn die Variable initialisiert wird, wird der gesamte Wert des initialisiert Objekt wird in der ausführbaren Datei gespeichert. Dies gilt auch dann, wenn nur der Anfangsteil explizit initialisiert wird (der Rest ist implizit Null).
  • Wenn die Variable konstant und initialisiert ist, befindet sie sich im Segment "Text" oder gleichwertig. Einige Systeme (moderne ELF-basierte, vielleicht auch Windows?) Haben ein separates "Rodata" -Segment für schreibgeschützte Daten, damit sie unabhängig vom Programmcode als nicht ausführbar markiert werden können.
  • Nicht konstante initialisierte Variablen befinden sich im Segment "data" in der ausführbaren Datei, das vom Betriebssystem beim Laden des Programms in den Speicher im Copy-on-Write-Modus gemappt wird.
  • Nicht initialisierte Variablen (die implizit Null gemäß dem Standard sind) haben in der ausführbaren Datei keinen reservierten Speicher, sondern eine Größe und einen Offset im "bss" -Segment, das zum Zeitpunkt des Programmladens vom Betriebssystem erstellt wird.
  • Solche nicht initialisierten Variablen können in einem separaten schreibgeschützten "bss" -ähnlichen Segment erstellt werden, wenn sie const -qualifiziert sind.