2012-06-24 18 views
8

Me pregunto por qué sigo recibiendo el error error: flexible array member not at end of struct cuando llamo malloc. Tengo una estructura con una matriz de longitud variable, y sigo recibiendo este error.¿Cuál es la causa del miembro de matriz flexible que no está al final del error struct?

La estructura es,

typedef struct { 
    size_t N; 
    double data[]; 
    int label[]; 
} s_col; 

y la llamada a malloc es,

col = malloc(sizeof(s_col) + lc * (sizeof(double) + sizeof(int))); 

¿Es esta la llamada a malloc correcta?

Respuesta

14

Solo puede tener un miembro de matriz flexible en una estructura y siempre debe ser el último miembro de la estructura. En otras palabras, en este caso se ha equivocado antes de llamar al malloc, hasta el punto de que realmente no hay forma de llamar al malloc correctamente para esta estructura.

para hacer lo que parece querer (arrays del mismo número de data y label miembros), usted podría considerar algo como:

struct my_pair { 
    double data; 
    int label; 
}; 

typedef struct { 
    size_t N; 
    struct my_pair data_label[]; 
}; 

Tenga en cuenta que esto es un poco diferente, sin embargo: en lugar de una serie de double s seguido de una matriz de int s, le ofrece una matriz de uno double seguido de uno int, luego el siguiente double, el siguiente int, y así sucesivamente. Si esto es lo suficientemente cercano a lo mismo o no, dependerá de cómo use los datos (por ejemplo, para pasar a una función externa que espera una matriz contigua, probablemente deba hacer las cosas de manera diferente).

3
typedef struct { 
    size_t N; 
    double data[]; 
    int label[]; 
} s_col; 

No se puede tener miembro de matriz flexible (double data[]) en el medio. Considere el tamaño de matriz codificada o double *data

+0

No entiendo, me enseñan que "T * var" es lo mismo que "T var []" – spectre

+1

@ lukasz1985: Lo que dices es cierto en el contexto de un argumento de función, donde puedes especificar " un argumento de manipulación de matriz "que se implementa técnicamente por medio de un puntero. Normalmente (es decir, aquí) una matriz es una matriz, y un puntero es un puntero. – stan423321

2

Dada una definición de estructura y un puntero al inicio de una estructura, es necesario que el compilador de C pueda acceder a cualquier miembro de la estructura sin tener que acceder a nada más. Dado que la ubicación de cada elemento dentro de la estructura está determinada por el número y los tipos de elementos que le preceden, para acceder a cualquier elemento es necesario conocer el número y los tipos de todos los elementos anteriores. En el caso particular en que el último elemento es una matriz, esto no presenta ninguna dificultad particular ya que acceder a un elemento en una matriz requiere saber dónde comienza (lo que requiere saber el número y tipo de anteriores a artículos, en lugar del número de elementos en la matriz en sí misma) y el índice del elemento (que el compilador puede suponer que es más pequeño que el número de elementos para los que existe espacio, sin tener que saber nada sobre el tamaño de la matriz). Sin embargo, si un Miembro de matriz flexible apareció en cualquier lugar que no sea al final de una estructura, la ubicación de los elementos que lo siguieron dependerá de la cantidad de elementos en la matriz, algo que el compilador no sabrá.

Cuestiones relacionadas