2009-02-16 12 views
5

Ho bisogno di avere un static void* array[1024]; in una libreria e ho bisogno di averlo impostato su NULL per ogni voce.C: array statico

La mia domanda riguarda il modo migliore per impostare l'intero array su NULL, è una memset (array, NULL, sizeof (void*) * 1024) la soluzione migliore?

risposta

24

static puntatori vengono inizializzati automaticamente NULL. Vedere C99: TC3 6.7.8, §10:

Se un oggetto con durata di memorizzazione automatica non è inizializzato in modo esplicito, il suo valore è indeterminato. Se un oggetto con durata di archiviazione statica non è inizializzato in modo esplicito, allora:

  • se ha il tipo di puntatore, viene inizializzato su un puntatore nullo;
  • se ha tipo aritmetico, è inizializzato allo zero (positivo o senza segno);
  • se è un aggregato, ogni membro viene inizializzato (in modo ricorsivo) in base a queste regole;
  • se è un unione, il primo membro denominato viene inizializzato (in modo ricorsivo) in base a queste regole.

Inoltre, contrariamente a ciò che altri hanno scritto,

memset(array, 0, sizeof(array)); 

non è garantito a causare puntatori nulli. Su alcuni sistemi, un puntatore con tutti i bit impostati su 0 potrebbe effettivamente essere valido. Per i sistemi mainstream, non è così, ma con i sistemi integrati, non si sa mai.

Il modo più sicuro per impostare tutte le voci di un puntatore nullo è a uno ciclo sulle voci stessi e metterli a NULL, o di utilizzare un non inizializzato static matrice cui è possibile memcpy() sopra la matrice che si desidera impostare per NULL.

+0

Sono curioso: qual è un esempio di un sistema per il quale il puntatore 0x00 è valido? – Crashworks

+0

Non ne ho mai visto uno (anche quelli incorporati), @Crashworks, ma lo standard dice che sono possibili, quindi è una buona idea tenerlo in considerazione se c'è una possibilità che il software possa mai funzionare lì. Il pragmatismo mi permette di ignorare tranquillamente questa regola :-) – paxdiablo

+0

@Crashworks: vedere http://www.lysator.liu.se/c/c-faq/c-1.html#1-14 – Christoph

0

No, è sbagliato. Non stai considerando la dimensione di ogni elemento.

memset(array, 0, sizeof(array)); // this works only on static arrays. 

In genere si dovrebbe usare:

memset(array_reference, 0, size_of_array * sizeof(array_element_type)); 
+0

ok, ma la mia domanda riguardava l'uso di memset, non i suoi argomenti. – claf

+0

claferri: la prima linea funziona per il tuo caso. La seconda riga è informazioni più generali (per notare che memset richiede la dimensione della matrice in byte, non il numero di elementi) –

9
static void* array[1024] = {0}; 

o, come sottolinea kmkaplan nel commento fare:

static void* array[1024]; 

anche se io preferisco la prima soluzione solo per ricordare me che è impostato su zeri (il compilatore non dovrebbe generare alcun codice per questo a meno che non sia cerebralmente morto).

Non è necessario memset perché le variabili a livello di file sono inizializzate a zero in ogni caso.

Se è necessario ripristinare loro di NULL ad un certo punto dopo l'avvio, l'uso:

memset(array, 0, sizeof(array)); 

Questo funziona sulla maggior parte delle piattaforme (ognuno che abbia mai visto e questo è un bel po '), in quanto la il puntatore nullo è in genere zero bit. Ma la norma non garantisce questo modo, su queste piattaforme oscure, è più sicuro fare:

for (i = 0; i < sizeof(array)/sizeof(void*); i++) 
    array[i] = NULL; 
+0

è una chiamata implicita a memset? – claf

+0

Si noti che non è nemmeno necessario specificare la parte "= {0}". – kmkaplan

+0

Funziona solo per l'inizializzazione. Potrebbe essere necessario utilizzare memset in una funzione di libreria per reimpostare i valori in fase di esecuzione. –

3

memset lo farà in runtime.

static void* array[1024] = {0}; 

suggerito da Pax lo farà in fase di compilazione e aumenterà la dimensione del file eseguibile.

Per una biblioteca credo che memset sia più appropriato.

1

Tutto ciò che serve è:


static void* array[1024]; 

perché le variabili statiche vengono inizializzate a 0 in ogni modo, in modo che non ha realmente bisogno di avviare questo array, che avverrà automaticamente.