2009-05-26 16 views
9

Ho bisogno di trasferire pacchetti attraverso Internet la cui lunghezza deve essere dinamica.C: stile consigliato per strutture di dimensioni dinamiche

struct packet 
{ 
    int id; 
    int filename_len; 
    char filename[]; 
}; 

Il problema è che gli array a lunghezza zero non sono conformi ISO.

Devo utilizzare char filename[1];? Ma allora sizeof(struct packet) non restituirà più il valore corretto.

risposta

6

Problema classico. Puoi semplicemente gestirlo (e notare che sizeof (foo) può essere disattivato più di uno se il compilatore arrotonda la dimensione della struttura, che è (credo) permesso, o puoi fare qualcosa del genere:

struct packetheader { 
    int id; 
    int filename_len; 
}; 
struct packet { 
    struct packetheader h; 
    char filename[1]; 
}; 

Questo è fastidioso (devi usare h.id, ecc.), Ma funziona. Di solito mi occupo solo di questo, ma quanto sopra potrebbe essere leggermente più portatile.

6

Penso che dovresti esaminare alcuni esempi esistenti di strutture dimensionate dinamicamente come guida. Il miglior esempio che conosco sono le API TOKEN in Win32. Usano l'ANYSIZE_ARRAY macro che risolve proprio in fondo a 1. Raymond Chen ha fatto un ampio articolo di blog in dettaglio esattamente perché sono fatto in questo modo

Per quanto riguarda operazioni come sizeof fallendo. Ciò non riuscirà a prescindere dalla soluzione scelta per una struttura di dimensioni dinamiche. sizeof è un'operazione in fase di compilazione e sarà necessario ridimensionare la struttura in fase di esecuzione. Semplicemente non può funzionare.

+0

con sizeof intendevo solo la dimensione della struct, non il campo dinamico, perché quando ricevo il pacchetto UDP, prima leggo nella struct che contiene la dimensione del campo dinamico, quindi leggo il campo dinamico. – codymanix

4

Suggerisco di utilizzare char filename[1] e includere un 0 byte di terminazione. In questo modo, è possibile malloc() la dimensione struttura corretta ed evitare errori una tantum come questa:

ptr = malloc(sizeof(struct packet)+filename_len); 
strncpy(&ptr->filename, filename, filename_len); 

Ma il ricevitore deve sapere che ha bisogno di leggere filename_len+1 byte.

3

Infatti lo zero-length arrays non fa parte dello standard. Ma quello che hai nel tuo snippet di codice è un array flessibile che fa parte dello standard ISO C99. Se è possibile utilizzare C99, utilizzerei un array flessibile, se il suggerimento di jesup è probabilmente il migliore.

Problemi correlati