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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4379672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:19:42  来源:igfitidea点击:

invalid use of flexible array -flexible struct array as a member of another struct

cstruct

提问by dubbeat

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:

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

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

编辑 1

It's something like this I am trying to achieve

我正在努力实现这样的目标

flexible length struct array inside another struct using C

使用 C 的另一个结构中的灵活长度结构数组

EDIT 2*

编辑 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 是否与 B 相同。 B 将是我的首选方法,但我不知道它是否正确。我对 a 很有信心,因为当我调试通道时,我看到了 channel[0]、channel[1]channel[2] 等。列出了通道结构的变量。

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****

**编辑 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;

回答by Robert S. Barnes

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 NOTa 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 mydatapointer and then the varDataSizefield 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 datais NOTa pointer.

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

Old Answer:

旧答案:

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

我认为这仅在 C99 标准中允许。尝试使用-std=c99标志编译。

Also, see this thread, Variable array in struct

另外,请参阅此线程,结构中的变量数组

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

另请参阅此 SO 帖子:C 中的灵活数组成员 - 坏吗?

回答by anatolyg

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 enginevariable in the following line:

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

struct enginestruct engine,*engineptr;