【问题标题】:invalid use of flexible array -flexible struct array as a member of another struct无效使用灵活数组 - 灵活结构数组作为另一个结构的成员
【发布时间】:2010-12-07 17:31:00
【问题描述】:

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

灵活数组的使用无效

我做错了什么?

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

好的,所以我似乎以错误的方式接近创建可变大小的结构数组。我有两件事正在尝试。我知道的第一个肯定有效。第二个我想如果有人可以为我检查一下。我仍在学习指针,想知道 A 是否与 B 相同。B 将是我的首选方法,但我不知道它是否正确。我对 a 很有信心,因为当我调试通道时,我会看到 channel[0]、channel[1]channel[2] 等。但我对 B 不太有信心,因为当我调试它时,我只看到内存地址和列出了通道结构的变量。

一个

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

【问题讨论】:

  • 您使用的是什么平台和编译器?
  • 我使用的是 ios4 和 gcc 4.2。我已经遵循了很多例子,但我就是无法破解它

标签: c struct


【解决方案1】:

编辑

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

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?

【讨论】:

  • 设置该标志似乎并没有让我摆脱错误。我正在阅读链接。
  • 嗯嗯嗯。这很难让我明白。您能否指出一个说明上述数据包示例的示例的正确方向?还可以安全地假设这种灵活的数组方法不适合结构类型,还是我正在尝试这样做?
  • @dubbeat:在另一个结构中拥有一个可变的结构数组是没有问题的。请记住,var 数组必须是外部结构的最后一个成员,并且只有最外部的结构才能具有变量数组。查看 TCP 数据包的格式,这是一个完美的示例:networksorcery.com/enp/protocol/tcp.htm 如果您仍然不明白,请告诉我,也许我可以在今晚晚些时候写一个更深入的示例。
  • @dubbeat:另外一个建议,好像你真的不需要使用变量数组,为什么不直接在enginestruct中使用指针呢?这将立即解决您的问题。
  • @罗伯特。您能否看看我的“编辑 2 方法 B”并告诉我它是否有效?
【解决方案2】:

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

struct enginestruct engine,*engineptr;

【讨论】:

  • 当然你可以定义 struct 类型的对象——它是什么——
  • 如果你可以定义它,它的大小是多少(编译器需要知道这一点才能将它放入结构体或堆栈中)?我猜如果可以定义,数组部分的大小将是0,所以它不会很有用。
猜你喜欢
  • 2011-07-25
  • 2011-03-04
  • 2012-09-22
  • 2020-04-13
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多