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

C 灵活数组的使用无效-灵活结构数组作为另一个结构的成员,c,struct,C,Struct,我开始学习如何在C语言中使用structs,这是一种挑战和享受。不用说,我遇到了一个似乎无法解决的问题。我试图将一个灵活的结构数组作为另一个结构的成员,但遇到了一个错误: 灵活数组的使用无效 我做错了什么 #define NUM_CHANNELS 4 struct channelStruct { float volume; uint mute; }; struct enginestruct { float bpm; int synctimeinbeats;

我开始学习如何在C语言中使用structs,这是一种挑战和享受。不用说,我遇到了一个似乎无法解决的问题。我试图将一个灵活的结构数组作为另一个结构的成员,但遇到了一个错误:

灵活数组的使用无效

我做错了什么

#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

我正努力做到这一点

编辑2*

好的,我似乎以错误的方式创建了一个可变大小的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?
};
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;
**编辑3****

是的,他们是一样的。不确定你什么时候会用一个而不是另一个

channel channels[NUM_CHANNELS]; 
等于:)

编辑

我想我现在记得问题是什么了。当您声明一个结构,并将一个灵活的数组作为它的最后一个成员时,它所做的事情与您所想的完全不同

struct channelStruct channels[];
不是指针,它是一个与结构相邻的就地数组

使用这种方法的目的是将结构放置在现有块内存上。例如,当您有一个具有可变长度数据的数据包时,这在联网中非常有用。所以你可以做一些类似的事情:

struct mydata {
    // various other data fields
    int varDataSize;
    char data[];
}
当您收到一个数据包时,您将指向该数据的指针投射到
mydata
指针,然后
varDataSize
字段会告诉您得到了多少。就像我说的,需要记住的是,它都是一个连续的内存块,
数据
不是一个指针

旧答案:

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

再看这条线,


也可以看到这篇文章:

我不是这个C特性的专家,但我的常识告诉我,您不能定义类型为
struct enginestruct
的对象,只能定义指针。这与以下行中的
发动机
变量有关:

struct enginestruct engine,*engineptr;

您使用的是什么平台和编译器?我使用的是ios4和gcc4.2。我已经学了很多例子,但我就是无法破解它,因为标志似乎并没有消除我的错误。我正在浏览这些链接。这很难让我动脑。你能给我指出一个说明上述数据包示例的正确方向吗?还可以安全地假设这种灵活的数组方法不适合结构类型,或者这只是我尝试的方式吗?@typeat:在另一个结构中有一个结构的可变数组是没有问题的。请记住,var数组必须是外部结构的最后一个成员,并且只有最外层的结构才能有变量数组。看看TCP数据包的格式,这是一个很好的例子:如果您仍然不理解,请告诉我,也许我可以在今晚晚些时候写一个更深入的例子。@typelat:另一个建议,似乎您真的不需要使用变量数组,为什么不在enginestruct中使用指针呢?“这会立即解决你的问题。”罗伯特。你能看看我的“edit 2 method B”并让我知道它是否有效吗?当然你可以定义struct类型的对象-如果你能定义它,它是什么,它有多大尺寸(编译器需要知道这一点才能将它放入结构或堆栈中)?我猜,如果可以定义,数组部分的大小将为0,因此它不会非常有用。
struct enginestruct engine,*engineptr;