2009-11-04 13 views

risposta

19

dimensioni Array devono essere conosciute con ANSI 89 C. Il 99 versione della specifica rimosso questa limitazione e consentito array di dimensioni variabili.

Ecco l'alcuna documentazione la versione GNU di questa funzionalità

+0

Oh capisco. grazie. quindi tutti gli elementi dell'array si trovano ancora nello stack? – root

+0

Sì, lo sono. Se ciò non funziona, usa malloc come suggerito in altre risposte. –

4

Se è necessario allocare un array con dimensioni dinamica, è necessario ottenere dal mucchio, con malloc().

int *a = (int*)malloc(sizeof(int) * s) 
+2

Se si rilascia il cast '(int *)', il compilatore genera un errore se si dimentica di includere il file che definisce 'malloc'. Quindi è meglio non includere il cast. –

+1

'int * a = malloc (s * sizeof * a)' – AnT

0

Stai confondendo due cose qui.

1) Determinazione della dimensione di un array già allocato (che il titolo implica): dividere sizeof() per il totale per il formato di uno (per esempio, il primo) elemento:

sizeof(a)/sizeof(a[0]) 

2) dinamicamente ripartizione memoria come richiesto dalla tua domanda:

int *a = (int*)malloc(s * sizeof(int)); 
+0

sizeof (a)/sizeof (a [0]) determina la dimensione di un array in fase di compilazione, non in fase di esecuzione se è allocata nello stack come una dichiarazione di array. –

1

Questo codice è supportato dalle specifiche del linguaggio C99. Questo codice è anche supportato dal compilatore GCC in modalità C89/90 come estensione.

Quindi, la risposta alla tua domanda (perché funziona ") dipende da come la stai compilando. In generale, questo non verrà nemmeno compilato da un compilatore C89/90.

0

È importante capire in che modo la memoria viene allocata alla variabile da un compilatore per fornire una risposta adeguata alla domanda. Ci sono due modalità in cui la memoria è allocata alla variabile, può essere su un heap o può essere su una pila. La memoria su un heap è allocata dinamicamente. Quindi una variabile che alloca memoria su un heap può essere data la sua dimensione durante il tempo di esecuzione.

Gli array in caso di C vengono memorizzati in una pila. Per fornire memoria su una pila, la dimensione della memoria dovrebbe essere nota al compilatore durante la compilazione. In modo che durante il runtime sia possibile dedicare molta memoria alla variabile in pila. Questo è il motivo per cui non è possibile decidere la dimensione dell'array in fase di esecuzione per quanto riguarda il linguaggio C.

+1

L'allocazione della memoria nello stack è semplicemente una questione di regolazione del puntatore dello stack - e non vi è * nessun * motivo fondamentale per cui il puntatore dello stack può essere regolato solo con valori noti al momento della compilazione. In effetti, il più recente standard C consente variabili automatiche le cui dimensioni sono determinate in fase di esecuzione, e c'è anche un'estensione comune 'alloca()' che ha fornito la stessa cosa per anni prima * che *. – caf

0

Variable Length Arrays fanno parte del linguaggio C dal C99. Ma sono stati creati come funzionalità in C11 - il che significa che un'implementazione conforme a C11 non ha bisogno di fornirli (anche se praticamente tutte le implementazioni che supportano C99 forniscono certamente VLA in C11).

È possibile verificare se l'implementazione non fornisce VLA utilizzando la macro __STDC_NO_VLA__ (Se è definita in modalità di compilazione C99 o C11, l'implementazione non supporta VLA).

Quindi decidere una dimensione della matrice in fase di esecuzione è possibile in moderna C (> = C99) e il codice come il sotto va bene:

int s; 
printf("Enter the array size: "); 
scanf("%d", &s); 
int a[s]; 

Una evidente svantaggio di Vlas è che se s è abbastanza grande e la assegnazione di a fallire coud. Peggio ancora, non c'è modo di verificare se l'allocazione non è riuscita e si verificheranno errori di runtime (ad esempio, segfault). È essenzialmente undefined behaviour. Quindi, , si desidera evitare VLA se la dimensione dell'array è troppo grande. Fondamentalmente, in caso di dubbio, andare per l'allocazione dinamica della memoria (vedi sotto).

Un altro problema, molto meno grave rispetto ad altri, con gli VLA è che hanno la durata di archiviazione automatica (ovvero "stack allocato"). Quindi, se si desidera qualcosa che dura per una durata più lunga, lo scope del blocco in cui viene dichiarato VLA, quindi VLA non sono di aiuto.

In C89, non c'è VLA. Quindi usare l'allocazione dinamica della memoria è l'unico modo. Sebbene ci fossero alcune estensioni non standard come alloca() che è simile a VLA e presenta gli stessi svantaggi dei VLA).

int s; 
printf("enter the array size: "); 
scanf("%d",&s); 
int *a = malloc(s * sizeof *a); 
... 
free(a); 
Problemi correlati