2012-10-13 11 views
15

Garantisco che questa domanda sia stata richiesta in precedenza, ma non sono stata in grado di trovarla tramite la ricerca; mi dispiace in anticipo per eventuali licenziamenti.Istanziazione array C - Assegnazione stack o heap?

È la mia comprensione (potenzialmente errata) che si assegna alla pila solo quando si conosce la dimensione di un oggetto in fase di compilazione. Quindi, nel caso di inizializzazione di un array, si potrebbe fare uno di questi (e questo dovrebbe andare in pila):

char charArray[50]; 

Poiché la dimensione di questo array è noto al momento della compilazione, questo dovrebbe avere problemi.

D'altra parte, questo (credo) è anche codice valido:

char anotherCharArray[someVariable + 50]; 

sarebbe questo vanno in pila come bene? Sono abbastanza sicuro che il codice segfaults se sei libero(), quindi mi fa pensare che lo faccia, ma non ha senso per me. Allo stesso modo, è la sola situazione del 100% in cui è necessario utilizzare free() quando i dati sono stati assegnati tramite malloc?

Grazie in anticipo per il vostro aiuto.

+2

@Shookit: è necessario specificare se si tratta di variabili locali o globali. –

+0

@PaulR se la matrice è di lunghezza variabile, non può essere nell'ambito globale. –

+1

È necessario distinguere tra * storage automatico * e * stack *, che è un modo di livello basso per memorizzare i dati. I dati inseriti nella memoria automatica possono essere collocati anche in altri luoghi, come nei registri. Nel caso di un array locale con una dimensione sconosciuta (nota come VLA: s), il compilatore può posizionarlo nello stack, è anche permesso allocare la memoria sull'heap (a patto che venga rilasciato nelle posizioni appropriate). In effetti, VLA: s non va bene insieme a 'setjmp' /' longjmp' in quanto potrebbero perdere (e sono autorizzati a farlo dallo standard C). – Lindydancer

risposta

4

Analogamente, è la sola situazione del 100% in cui è necessario utilizzare free() quando i dati sono stati assegnati tramite malloc?

Sì. (Oltre a calloc e realloc, anche il loro valore di ritorno è free() "d) Allo stesso modo, ci sono funzioni che usano malloc() e questo fatto è documentato, ad esempio strdup() - il valore di ritorno di queste funzioni deve anche essere liberato usando free(), ovviamente.)

char anotherCharArray[someVariable + 50]; 

sarebbe questo vanno in pila come bene?

Sì, lo fa (nella maggior parte delle implementazioni - naturalmente, non è sempre vero che si assumono, ma sulla maggior parte delle piattaforme, lo è). E sì, questo è un codice valido, ma è solo standard in C99.

+0

Va bene, quindi sembra che il mio più grande malinteso sia stato ipotizzare che l'allocazione della memoria dello stack richieda la conoscenza della dimensione al momento della compilazione? Ho contrassegnato questo come risposta (ma sento comunque libero di rispondere al mio commento :) – Shookit

+6

@Shookit Sì, questo è un malinteso completo; avere una dimensione nota è irrilevante per dove viene assegnato qualcosa. L'unica connessione è che, nelle versioni precedenti di C, per varie ragioni storiche, le variabili 'auto' dovevano avere una dimensione nota e solo le variabili' auto' possono essere allocate nello stack. –

+0

@JimBalter ha risposto molto bene alla tua domanda :) –

7

Se char charArray[50]; è definito nell'ambito di file (al di fuori di tutte le funzioni) o è static, non sarà in pila, sarà un preallocato globale alla variabile iniziale del programma. Se non è static ed è definito nell'ambito della funzione, sarà in pila.

char anotherCharArray[someVariable + 50]; può essere definito solo nell'ambito della funzione e sta per essere in pila.

Tutti i precedenti si applicano alle implementazioni tipiche di C. Atipici possono utilizzare l'heap anziché lo stack e invece lo spazio preallocato nella sezione dati del programma.

non vi free() ciò che non è stato assegnato con malloc(), calloc() o realloc(). Semplice. Alcune funzioni possono implicare l'uso di uno dei precedenti, ad es. POSIX strdup().

+1

Se siamo nell'ambito globale, 'char someArray [variableLenght]; 'non è consentito ... –

+0

@ H2CO3 La modifica più recente ha rimosso l'ambiguità? Non vedo dove implicheremo che ciò sia consentito nell'ambito globale. –