invalid use of flexible array -flexible struct arr

2020-06-03 03:55发布

问题:

I'm beginning to learn about the use of structs in C. It's challenging and enjoyable. Needless to say I've encountered a problem I can't seem to figure out. I'm trying to make a flexible struct array as a member of another struct but I'm getting an error:

invalid use of flexible array

What am I doing wrong?

#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

It's something like this I am trying to achieve

flexible length struct array inside another struct using C

EDIT 2*

O.K so I seem to be approaching the creation of a variable sized array of struct the wrong way. I have 2 things that I'm trying. The first I know works for sure. The second I would just like if somebody could sanity check it for me. I'm still learning about pointers and would like to know if A is the same as B. B would be my preferred method but I don't know if its correct. I'm confident about a because when I debug channels i see channel[0],channel[1]channel[2] etc. But I'm not so confident about B because when I debug it I only see an address to memory and the variables of channel struct listed.

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;

**EDIT 3****

Yep they are the same. Not sure when you would use one over the other tho

channel channels[NUM_CHANNELS]; 

Is Equal To :)

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;

回答1:

Edit

I think I remember now what the problem is. When you declare a struct with a flexible array as it's last member it's doing something completely different than what you think.

struct channelStruct channels[];

is NOT a pointer, it is an in place array which is contiguous with the struct.

The way this is intended to be used is to lay the struct over an existing block memory. For instance, this is useful in networking when you have a packet with variable length data. So you might do something like:

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

When you receive a packet you cast a pointer to the data to a mydata pointer and then the varDataSize field tells you how much you've got. Like I said, the thing to remember is that it's all one contiguous block of memory and data is NOT a pointer.

Old Answer:

I think that's only allow in the C99 standard. Try compiling with the -std=c99 flag.

Also, see this thread, Variable array in struct

Also see this SO post: Flexible array members in C - bad?



回答2:

I am not an expert in this C feature but my common sense tells me that you cannot define objects of the type struct enginestruct, only pointers. This regards the engine variable in the following line:

struct enginestruct engine,*engineptr;


标签: c struct