2010-12-30 22 views

Respuesta

15

En una palabra, sí.

Básicamente, la forma en C99 de hacerlo es con un flexible array member:

uint32 words[]; 

Algunos compiladores pre-C99 permiten escapar con:

uint32 words[0]; 

Pero la manera de garantizar que funcione en todos los compiladores es:

uint32 words[1]; 

Y luego, no importa cómo se declare, puede asignar el objeto ingenio h:

Bitmapset *allocate(int n) 
{ 
    Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof(p->words[0])); 
    p->nwords = n; 
    return p; 
} 

Aunque para obtener los mejores resultados se debe utilizar en lugar de size_tint.

+0

Thanks. Entonces, ¿esta complicada asignación tiene un problema para el relleno de estructuras, por ejemplo, si el n pasado es un número impar? – Oxdeadbeef

+0

@Oxdeadbeef - Sí, supongo. Realmente no almacenará una matriz de ellos en la memoria contigua. Si quisiera una matriz de ellos, probablemente sería mejor usar 'Bitmapset * a [20] = {NULL};' o 'Bitmapset ** a = malloc (20 * sizeof * a);'. –

+1

La sintaxis 'offsetof (Bitmapset, words [n])' es una extensión (que es compatible con la mayoría de los compiladores). Para cumplimiento estricto, use 'offsetof (Bitmapset, words) + n * sizeof (p-> words [0])'. – Jed

6

Esto es generalmente para permitir el acceso idiomático a instancias de estructuras de tamaño variable. Teniendo en cuenta su ejemplo, en tiempo de ejecución, es posible que tenga un Bitmapset que se presenta en la memoria de esta manera:

----------------- 
| nwords | 3 | 
| words[0] | 10 | 
| words[1] | 20 | 
| words[2] | 30 | 
----------------- 

por lo que terminan con un número de tiempo de ejecución variable de uint32 "colgando" al final de su estructura, pero accesible como si estuvieran definidos en línea en la estructura. Esto es básicamente (ab) utilizando el hecho de que C no hace ninguna comprobación de límites de matriz en tiempo de ejecución para permitirle escribir código como:

for (int i = 0; i < myset.nwords; i++) { 
    printf("%d\n", myset.words[i]); 
} 
+0

gracias. pero ¿cuál es la ventaja sobre el uso de palabras uint32 *? – Oxdeadbeef

+5

No funcionaría de la misma manera. Si hicieras eso, entonces las palabras [2] dirían "sigue el puntero ubicado en el campo 'palabras' de la estructura, luego ve 2 * 8 == 16 bytes más y accede a la memoria allí". Tendría que (por ej.,) malloc() una región de memoria separada para contener las palabras matriz en el montón, y esto podría afectar el rendimiento y la facilidad de uso. –

Cuestiones relacionadas