代码之家  ›  专栏  ›  技术社区  ›  jdizzle

零长度数组与指针

  •  21
  • jdizzle  · 技术社区  · 15 年前

    编辑:很明显,在各种C标准中,有些是不允许的/已经改变了。为了我自己的假设利益,我们假设 gcc test.c 没有标准或警告选项。

    特别是我在看引擎盖下的细节。我补充了我目前的理解。我说的对吗?

    char **c1;   //Size for a pointer is allocated on the stack. sizeof(c1) == sizeof(void*)
    char *c2[0]; //Nothing is allocated on the stack.  sizeof(c2) == 0
    

    这两个我不知道的案子还有什么区别吗(除了大小)?

    struct a {
       int i;
       char c[0]; //sizeof(a) is sizeof(int)?  a.c == (&i)+1?
    };
    

    据我所知,这通常用于结构末端的可变长度数组。但是呢

    struct b {
       char *c[0] //sizeof(b) is 0?  where does c point?
    };
    
    int j;
    struct b myb; //myb.c == (&j)+1 == $esp?
    

    此外,如果零长度数组指针的空间从未分配到任何位置,如何知道该数组的地址?我想知道常规数组地址的方法是一样的,但我现在正努力把心思放在它上面。

    5 回复  |  直到 8 年前
        1
  •  12
  •   Andrew Barrett    15 年前

    我唯一见过实际使用的零长度数组是当您想要一个可变长度的结构时。

    在这个例子中 here

        struct line {
           int length;
           char contents[0];
         };
    
         struct line *thisline = (struct line *)
           malloc (sizeof (struct line) + this_length);
         thisline->length = this_length;
    

    您不希望在上述结构中使用指针,因为您希望内容成为结构的已分配内存的一部分。

    如果对上述结构执行sizeof操作,则它不包含任何内容空间。我不确定这是否能成为一个标准,它会在各种编译器上发出警告。

        2
  •  9
  •   dirkgently    15 年前

    ISO C禁止 0 -长度数组。

    char **c1;
    

    这定义了一个对象 c1 指向指向char的指针的类型。

    char *c2[0];
    

    这是一个编译错误。不允许。不是C,不是C++。

    struct a {
      int i;
      char c[0]; //sizeof(a) is sizeof(int)?  a.c == (&i)+1?
    };
    

    如前所述的错误--数组的大小必须大于零。

     struct a {
      int i;
      char c[1]; 
    };
    

    也称为 结构黑客 . 几乎所有操作系统(Linux、Windows)的低级代码都被滥用。

    C99确实为我们提供了一个称为灵活阵列成员的无尺寸阵列:

    struct a {
      int i;
      char c[]; /* note: no size */ 
    };
    
        3
  •  2
  •   Aaron McDaid    13 年前

    你可以从这里得到一些答案 GCC docs . 但这主要集中在将零长度数组作为结构的最后一个成员这一主题上。它没有给出关于大小的直接答案。

    (正如其他人所说,零长度数组不在标准C中,但它们在GNU C中。)

        4
  •  1
  •   Jonathan Leffler    15 年前

    根据C99标准(7.20.3),处理分配功能:

    每一个这样的分配应产生一个指向与任何其他对象不相交的对象的指针。

    […]

    如果请求的空间大小为零,则行为是由实现定义的: 返回一个空指针,或者行为就好像大小是 非零值,但返回的指针不应用于访问对象。

    换句话说,在声明的情况下 b 在没有初始值设定项的堆栈上(其中 IS有 c 宣布为 c[] 而不是 c[0] )的实际大小 就实际使用的空间而言,>0,因为您无法访问 . 如果是通过 malloc ,它将作为 0 或者作为无法访问的唯一值(如果使用 sizeof(b) )

        5
  •  0
  •   The Beast    8 年前

    数组的大小不能为零。

    ISO 9899:2011 6.7.6.2:
    
    If the expression is a constant expression, it shall have a value greater than zero.
    

    上述文本对于普通数组(§1)和vla(§5)都是正确的。这是C标准中的规范性文本。编译器不允许以不同的方式实现它。

    gcc-std=c99-pedantic对此给出警告。