2009-12-14 14 views
26

In C, ho un array di struct definito come:Risultato di 'sizeof' su array di strutture in C?

struct D 
{ 
    char *a; 
    char *b; 
    char *c; 
}; 

static struct D a[] = { 
    { 
     "1a", 
     "1b", 
     "1c" 
    }, 
    { 
     "2a", 
     "2b", 
     "2c" 
    } 
}; 

Vorrei determinare il numero di elementi dell'array, ma sizeof(a) restituisce un risultato errato: 48, non 2. Sto facendo qualcosa sbagliato, o sizeof semplicemente inaffidabile qui? Se è importante sto compilando con GCC 4.4.

+0

Vedere http://stackoverflow.com/questions/1598773/is-there-a-standard-function-in-c-that-would-return-the-length-of-an-array/1598827#1598827 per una risposta che include alcuni hack per rendere le tecniche postate più sicure. –

risposta

27
sizeof a/sizeof a[0]; 

Questa è una fase di compilazione costante, si può utilizzare, ad esempio, creare un altro array:

#define N sizeof a/sizeof a[0] 
int n_a[N]; 
+0

In questo caso, se sizeof (a) è 48, sizeof (a [0]) == 24. Ciò fa sì che ogni char * occupi 8 byte. sizeof (char *) è probabilmente 4 o 8, a seconda di 32-bit/64-bit, ma i compilatori eseguiranno l'allineamento dei membri struct, quindi ogni elemento termina con 8 byte. – jmanning2k

+1

Sì, ma la cosa bella è che la divisione dà la dimensione corretta indipendentemente dal fatto che ci sia o meno il padding, o qualunque sia la dimensione della 'struct'. –

+0

#define non dovrebbe avere un punto e virgola alla fine – Paamand

37

sizeof si dà la dimensione in byte, non il numero di elementi. Come dice Alok, per ottenere il numero di elementi, dividere la dimensione in byte dell'array in base alla dimensione in byte di un elemento. La corretta C linguaggio è:

sizeof a/sizeof a[0] 
+7

+1 per dare una spiegazione migliore. –

+10

Una versione alternativa, semplicemente idiomatica è 'sizeof a/sizeof * a' – caf

7

sizeof restituisce la dimensione in memoria dell'elemento passato. Dividendo la dimensione di un array per una singola dimensione di elemento, si ottiene il conteggio degli elementi.

Si noti che la dimensione dell'elemento può includere anche alcuni byte di riempimento. Per questo motivo, una struttura riempita (ad esempio quando un membro char è seguito da un puntatore) avrà un valore sizeof superiore alla sua dimensione di membri.

D'altra parte, non lasciarti disturbare durante il conteggio degli elementi in un array: sizeof(a)/sizeof(a[0]) continuerà a funzionare in modo uniforme come previsto.