【问题标题】:Is this a Flexible Array Struct Members in C as well? [duplicate]这也是 C 中的灵活数组结构成员吗? [复制]
【发布时间】:2012-11-29 09:39:37
【问题描述】:

可能重复:
Flexible array members in C - bad?

我阅读了以下代码:

struct hello {
    int number;
    int data[1];
};

我知道灵活数组成员允许我们将最后一个元素声明为array of unspecified size,如下所示:

struct hello {
    int number;
    int data[];
};

在这个struct中,最后一个元素没有指定大小,那么这两者有什么区别呢?第一个声明是什么意思?

【问题讨论】:

  • 你可能会在这里得到答案:stackoverflow.com/questions/246977/…
  • data[1]和data[0]有什么区别?
  • int data[1] 表示名为 data 的 int 数组的大小为 1 int。但是当你必须访问它时,你必须访问数组的第一个(也是唯一一个)元素,然后你会做这样的事情:myHelloStruct.data[0]=200(这是一个例子)。

标签: c arrays struct


【解决方案1】:

这种数组:

struct hello {
    int number;
    int data[];
};

仅作为结构的最后一个元素才有意义,并且仅在您从堆中分配结构时才有意义,并且通常使标头字段包含数组的实际大小:

struct hello *helloptr = malloc(sizeof (struct hello) + count*(sizeof int));
helloptr->number = count;

用途是用一个结构体方便地分配header和data buffer。

补充:分配大小为 1 的数组的版本与分配大小为 1 的数组的区别在于,sizeof struct hello 会更多,因为数组分配有一个元素,而不是 undefined=0。这要么浪费一个项目的内存,要么使大小计算更加复杂,并且在概念上有点“丑陋”(你的代码有大小为 1 的数组,而实际上你的意思是“未定义”,甚至可能是 0)。

在 OOP C++ 中,最好将动态分配的缓冲区包装在一个类中,这真的是一种“黑客”。

【讨论】:

  • 没完全看懂,但是这两种不同的形式有什么不同吗?
  • @ratzip 不同的是,你的第一个结构(数组大小为 1)有sizeof 8,而第二个结构(有灵活数组)有sizeof 4,数组假定为零大小。
  • 据我了解,如果一个结构有一个成员unsigned char foo[1],编译器将被合法地允许用ptr->foo[0] 替换ptr->foo[intexpr],因为intexpr 的任何值都会超出要么 为结构分配的物理空间或foo 的指定维度将产生未定义的行为。 struct hack 的单项数组版本很常见,我不希望编译器将这种优化应用于通过 ptr 访问的结构的最后一项,但我不知道有什么会禁止他们这样做.
【解决方案2】:

它不是一个灵活的数组成员,但在一些需要与旧编译器或 c++ 编译器一起使用的代码中使用。

将它用作灵活的数组成员可能会引发未定义的行为。在实际代码中,这应该可以按预期工作,因为这个技巧用于太多代码,编译器无法做出任何意想不到的事情。

【讨论】:

    【解决方案3】:

    data[1]data[0]有什么区别?

    没有区别,两者都可以用于实现灵活大小的结构。

    陈瑞文answers it aptly

    好吧,你可能会说,那为什么不使用长度为零的数组而不是长度为 1 的数组呢?

    因为时间旅行尚未完善。

    零长度数组直到 1999 年才成为合法的标准 C。由于 Windows 早在那之前就已经存在,它无法利用 C 语言中的这一功能。

    请注意,从技术上讲,第二个代码示例都不是有效的 C++ 代码。[Ref 1] 但是很多现有代码都使用此功能,并且此代码几乎总是可以工作。


    [参考 1]参考:

    C++11 标准:8.3.4 数组

    T D 的声明中,D 的格式为

    D1 [ constant-expressionopt] attribute-specifier-seqopt
    

    ....... 如果常量表达式 (5.19) 存在,它应该是一个整数常量表达式并且它的值应该大于零

    【讨论】:

    • 那么为什么第一个不是无效的 C++ 呢?他在里面有一个1
    • @JensGustedt:你在编辑中发现了我。抱歉,打错了。
    【解决方案4】:

    即使您只访问第一个元素,两者在 C 中也不完全等价。一个灵活的数组可以有与固定大小的数组不同的对齐方式。因此,即使sizeof 可能会为您提供不同的结果,并且您永远不应该在同一代码中混合这两种变体。

    【讨论】:

      猜你喜欢
      • 2011-03-04
      • 2018-03-29
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      相关资源
      最近更新 更多