2010-12-07 14 views
8

Estoy empezando a aprender sobre el uso de estructuras en C. Es desafiante y agradable. Huelga decir que he encontrado un problema que parece que no puedo resolver. Estoy tratando de hacer una serie estructura flexible como un miembro de otra estructura, pero estoy recibiendo un error:uso no válido de matriz flexible-estructura de estructura flexible como miembro de otra estructura

invalid use of flexible array

¿Qué estoy haciendo mal?

#define NUM_CHANNELS 4 

struct channelStruct { 
    float volume; 
    uint mute; 
}; 


struct enginestruct 
{ 
    float bpm; 
    int synctimeinbeats; 
    int synctimeinsamples; 
    int currentbeat; 
    int oneBeatInSamples; 
    int samplerate; 
    struct channelStruct channels[]; 
}; 

struct enginestruct engine, *engineptr; 
struct channelStruct channel, *channelptr;   


-(void) setupengine 


{ 
    engineptr = &engine; 
    engineptr->oneBeatInSamples = 22050; 
    engineptr->samplerate = 44100; 

    struct channelStruct *ch = (struct channelStruct *) malloc ( 
     NUM_CHANNELS*sizeof(struct channelStruct)); 
    //error occurs here 
    engineptr->channels = ch; 
} 

EDIT 1

Es algo como esto que estoy tratando de lograr

flexible length struct array inside another struct using C

EDITAR 2 *

OK así que parecen estar acercándose a la creación de una matriz de tamaño variable de struct the w camino rápido. Tengo 2 cosas que estoy intentando. Lo primero que sé funciona con seguridad. En el segundo, me gustaría que alguien pudiera comprobarlo por mí. Todavía estoy aprendiendo sobre punteros y me gustaría saber si A es lo mismo que B. B sería mi método preferido, pero no sé si es correcto. Confío en que porque cuando depuro canales veo el canal [0], el canal [1] el canal [2] etc. Pero no estoy tan seguro acerca de B porque cuando lo depuro solo veo una dirección en la memoria y las variables de channel struct enumeradas.

A

// pretty sure this is o.k to do but I would prefer 
// not to have to set the size at compile time. 

struct enginestruct 
{ 
    float bpm; 
    int synctimeinbeats; 
    int synctimeinsamples; 
    int currentbeat; 
    int oneBeatInSamples; 
    int samplerate; 
    channel channels[NUM_CHANNELS]; //is this technically a pointer? 
}; 

B

//I'm not sure if this is valid. Could somebody confirm for me if 
//it is allocating the same amount of space as in A. 

struct enginestruct 
{ 
    float bpm; 
    int synctimeinbeats; 
    int synctimeinsamples; 
    int currentbeat; 
    int oneBeatInSamples; 
    int samplerate; 
    channel *channels; 
}; 

//This only works if channel in the engine struct is defined as a pointer. 
channel * ar = malloc(sizeof(*ar) * NUM_CHANNELS); 
engineptr->channels = ar; 

** EDITAR 3 ****

Sip que son la misma. No sé cuando se usaría una sobre la otra aunque

channel channels[NUM_CHANNELS]; 

es igual a :)

struct enginestruct 
{ 
    float bpm; 
    int synctimeinbeats; 
    int synctimeinsamples; 
    int currentbeat; 
    int oneBeatInSamples; 
    int samplerate; 
    channel *channels; 
}; 

channel * ar = malloc(sizeof(*ar) * NUM_CHANNELS); 
engineptr->channels = ar; 
+0

¿Qué plataforma y compilador está utilizando? –

+0

Estoy usando ios4 y gcc 4.2. He seguido muchos ejemplos, pero no logro romperlo – dubbeat

Respuesta

14

Editar

creo que recuerdo ahora cuál es el problema. Cuando declaras una estructura con una matriz flexible como su último miembro, estás haciendo algo completamente diferente de lo que piensas.

struct channelStruct channels[]; 

NO es un puntero, que es una matriz en el lugar que es contigua a la estructura.

La forma en que se pretende utilizar es colocar la estructura sobre una memoria de bloques existente. Por ejemplo, esto es útil en redes cuando tienes un paquete con datos de longitud variable. Así que se podría hacer algo como:

struct mydata { 
    // various other data fields 
    int varDataSize; 
    char data[]; 
} 

Cuando recibe un paquete que lances un puntero a los datos a un puntero mydata y luego el campo varDataSize le indica la cantidad que tienes.Como dije, lo que hay que recordar es que es todo un bloque contiguo de memoria y dataNO es un puntero.

respuesta antigua:

creo que sólo se permiten en el estándar C99. Intente compilar con la bandera -std=c99.

Además, vea este hilo, Variable array in struct

también ver este SO mensaje: Flexible array members in C - bad?

+0

al configurar esa bandera parece que no me libró del error. Estoy leyendo los enlaces. – dubbeat

+0

@dubbeat: Vea la edición de mi respuesta. –

+0

hmmmmm. eso es muy difícil de entender. ¿Podría apuntarme en la dirección correcta de un ejemplo que ilustre el ejemplo de dicho paquete? También sería seguro asumir que este método de arreglo flexible no es adecuado para los tipos de estructura o ¿es solo la forma en que trato de hacerlo? – dubbeat

0

no soy un experto en esta característica C, pero mi sentido común me dice que no se pueden definir los objetos del tipo struct enginestruct , solo punteros. Esto se refiere a la variable engine en la siguiente línea:

struct enginestruct engine,*engineptr; 
+1

por supuesto, puede definir objetos del tipo struct -what is- – dubbeat

+0

si puede definirlo, ¿qué tamaño tiene (el compilador necesita saber esto para ponerlo en una estructura o en la pila)? Supongo que si se puede definir, la parte de la matriz será de tamaño 0, por lo que no será muy útil. – Bwmat

+2

Lo siento, pero estás completamente equivocado. –

Cuestiones relacionadas