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

时间:2022-09-06 11:18:45

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

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

使用C的另一个struct内部的灵活长度struct数组

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.

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

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;

2 个解决方案

#1


15  

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.

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

Old Answer:

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

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

Also, see this thread, Variable array in struct

另外,请参阅此线程,struct中的Variable数组

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

另见SO帖子:C中的灵活阵列成员 - 不好?

#2


0  

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:

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

struct enginestruct engine,*engineptr;

#1


15  

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.

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

Old Answer:

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

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

Also, see this thread, Variable array in struct

另外,请参阅此线程,struct中的Variable数组

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

另见SO帖子:C中的灵活阵列成员 - 不好?

#2


0  

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:

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

struct enginestruct engine,*engineptr;