无效使用灵活数组 - 灵活结构数组作为另一个结构的成员

时间:2010-12-07 17:31:00

标签: c struct

我开始了解C中结构的使用。它具有挑战性和乐趣。不用说我遇到了一个我似乎无法弄清楚的问题。我正在尝试将灵活的struct数组作为另一个struct的成员,但是我收到了一个错误:

  

无效使用灵活数组

我做错了什么?

#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;
}

编辑1

这是我想要实现的事情

flexible length struct array inside another struct using C

编辑2 *

O.K所以我似乎正在接近以错误的方式创建一个可变大小的struct数组。我有两件事正在尝试。我知道的第一个肯定是有效的。第二个我愿意,如果有人能够理智地检查它。我还在学习指针,想知道A是否与B相同.B是我的首选方法,但我不知道它是否正确。我对a有信心,因为当我调试频道时,我看到频道[0],频道[1]频道[2]等。但我对B不太自信,因为当我调试它时我只看到一个地址到内存和列出的渠道结构的变量。

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?
};

//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;

**编辑3 ****

是的,他们是一样的。不确定何时使用一个而不是另一个

channel channels[NUM_CHANNELS]; 

等于:)

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;

2 个答案:

答案 0 :(得分:17)

修改

我想我现在记得问题是什么。当你声明一个具有灵活数组的结构作为它的最后一个成员时,它正在做一些与你想象的完全不同的事情。

struct channelStruct channels[];

不是指针,它是一个与结构相邻的就地数组。

打算使用的方法是将结构放在现有的块内存上。例如,当您拥有包含可变长度数据的数据包时,这在网络中很有用。所以你可以这样做:

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

当您收到数据包时,您将指向数据的指针转换为mydata指针,然后varDataSize字段会告诉您已经获得了多少数据。就像我说的那样,要记住的是,它是一个连续的内存块,data 不是指针。

旧答案:

我认为这只是在C99标准中允许的。尝试使用-std=c99标志进行编译。

另外,请参阅此主题Variable array in struct

另见SO帖子:Flexible array members in C - bad?

答案 1 :(得分:0)

我不是这个C功能的专家,但我的常识告诉我,你不能定义struct enginestruct类型的对象,只能指定指针。这涉及以下行中的engine变量:

struct enginestruct engine,*engineptr;