2015-09-02 9 views
6

Ho incontrato un fenomeno strano in C che mi serve qualcuno per spiegare. Ho il codice qui sotto con 2 array di singoli elementi come variabili globali. Sono stampando l'indirizzo di memoria del primo e secondo elemento di ciascun array (nota che l'array è stato definito per avere solo 1 elemento):L'allocazione della memoria di array in C dipende dalla convenzione di denominazione?

#include <stdio.h> 

int a1[1]; 
int a2[1]; 

int main(void) { 

    a1[0] = 100; 
    a2[0] = 200; 

    printf("%d\n", &a1[0]); 
    printf("%d\n", &a1[1]); 
    printf("%d\n", &a2[0]); 
    printf("%d\n", &a2[1]); 
} 

Questa pronunciato la seguente output. Si noti che C allocato un blocco di memoria contiguo per matrice a2 subito dopo a1 (quindi indirizzo a1 [1] e a2 [0] sono uguali):

4223424 
4223428 
4223428 
4223432 

Tuttavia, qualcosa miracolo si verifica quando cambio i nomi degli array. Ho aggiunto "zzz" come prefisso ad entrambi gli array come sotto.

#include <stdio.h> 

int zzza1[1]; 
int zzza2[1]; 

int main(void) { 

    zzza1[0] = 100; 
    zzza2[0] = 200; 

    printf("%d\n", &zzza1[0]); 
    printf("%d\n", &zzza1[1]); 
    printf("%d\n", &zzza2[0]); 
    printf("%d\n", &zzza2[1]); 
} 

Dopo aver eseguito questo codice è possibile vedere dalla seguente output che la memoria è allocata per la zzza2 matrice prima e successivamente per zzza1 (& a2 [1] = & a1 [0]):

4223428 
4223432 
4223424 
4223428 

Ho testato il codice precedente con più dimensioni di array (2,4,8) in varie macchine diverse in tempi diversi e ho ottenuto lo stesso risultato, quindi non è una coincidenza. Questo non accade quando definisco le variabili all'interno di main() come variabili locali.

Sembra che C stia allocando memoria in base al nome che forniamo agli array. In primo luogo, perché C assegna ogni volta blocchi contigui a diversi array globali? In secondo luogo, quando aggiungo il prefisso, perché l'ordine di allocazione della memoria cambia?

Spero che questo non sconcertino tutti perché ha me ... Grazie per il vostro aiuto in anticipo!

+4

La toolchain (il linker) è più o meno libera di posizionare oggetti a qualunque indirizzo voglia. Forse il nome degli oggetti entra in una sorta di struttura dati basata su un hash del nome e che influenza l'ordine di layout? Chissà? Vedi http://stackoverflow.com/questions/4575697/unexpected-output-from-bubblesort-program-with-msvc-vs-tcc/4577565#4577565 per un'altra situazione in cui il nome della variabile influenzava il layout della variabile (dal compilatore anziché il linker). –

+0

Sono curioso di sapere quale sia il risultato con a2 [] dichiarato prima di a1 []. Se è uguale al tuo primo test, suppongo che il compilatore faccia riferimento a una variabile in una sorta di tabella hash e produca il codice che lo legge in sequenza. E tutti i compilatori usano lo stesso algoritmo di hash. –

+0

Ad ogni modo, non dovresti fare ipotesi su come le variabili sono disposte in memoria. –

risposta

1

In primo luogo, perché C assegna i blocchi contigui a diversi array globali ogni volta?

Perché un blocco contiguo è più efficace e più facile da implementare. Se l'applicazione alloca variabili globali in diversi blocchi di memoria, presenta almeno uno dei seguenti inconvenienti:

  1. Memoria sprecata tra i blocchi.
  2. Allocazione di memoria complicata all'avvio.

Così toolchain tenta di allocare tutte le variabili globali in un blocco di memoria contigua.

Problemi correlati