2009-05-26 13 views
9

Necesito transferir paquetes a través de Internet, cuya longitud debe ser dinámica.C: Estilo recomendado para estructuras de tamaño dinámico

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

El problema es que las matrices de longitud cero no son compatibles con ISO.

¿Debo usar char filename[1]; en su lugar? Pero entonces sizeof(struct packet) ya no devolverá el valor correcto.

Respuesta

6

Problema clásico. Simplemente puede manejarlo (y tenga en cuenta que sizeof (foo) puede estar desactivado en más de uno si el compilador redondea el tamaño de la estructura, que es (creo) permitido), o puede hacer algo como esto:

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

Esto es molesto (tienes que usar h.id, etc.), pero funciona. Usualmente trato con que sea uno, pero lo anterior podría ser marginalmente más portátil.

6

Creo que aquí debe buscar algunos ejemplos existentes de estructuras de tamaño dinámico. El mejor ejemplo que conozco son las API TOKEN en Win32. Utilizan el ANYSIZE_ARRAY macro que acaba resuelve a 1. Raymond Chen hizo un extenso artículo en el blog que detalla exactamente por qué se hacen de esta manera

En cuanto a las operaciones tales como sizeof no. Esto fracasará sin importar qué solución elijas para una estructura de tamaño dinámico. sizeof es una operación en tiempo de compilación y se volverá a dimensionar la estructura en tiempo de ejecución. Simplemente no puede funcionar.

+0

con sizeof Quise decir solo el tamaño de la estructura, no el campo dinámico, porque cuando recibo el paquete UDP leo por primera vez en la estructura que contiene el tamaño del campo dinámico, y luego leo el campo dinámico. – codymanix

4

Sugiero usar char filename[1] e incluir un 0-byte de terminación. De esta manera, se puede malloc() el tamaño de la estructura correcta y evitar errores de una sola vez de esta manera:

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

Sin embargo, el receptor debe saber que tiene que leer filename_len+1 bytes.

3

De hecho zero-length arrays no son parte de la norma. Pero lo que tiene en su fragmento de código es una matriz flexible que es parte del estándar ISO C99. Si es posible usar C99, usaría una matriz flexible, si no la sugerencia de jesup es probablemente la mejor.

Cuestiones relacionadas