0

我知道零长度数组的用法,我想知道以下是否可以接受

struct foo {

    int id_num;
    bool is_person;
    char person_name[0];
    char product_name[0];

}foo;

 and allocating as follows

#define NAME_SIZE 100

struct foo *data = (struct foo\*)malloc(sizeof(struct foo) + NAME_SIZE);

我有上面用来表示一个人的结构。现在我想用同样的结构来表示一个产品。该结构将根据 is_person 标志引用产品或人员。我不想将最后一个成员放在联合中,因为这将涉及现有代码库中的大量代码更改。因此,我以上述方式对其进行了修改,并对其进行了编译。我想知道这是否是一个正确的用法,因为我要么将它用作人或产品,而不是两者兼而有之,而且我不想将变量名称更改为像char person_or_product_name[0]. 我还假设它person_name充当product_name同一内存区域的标识符。

4

2 回答 2

1

我还假设 person_name 和 product_name 充当同一内存区域的标识符。

确切地。这就是这里的实际问题:零长度数组是否占用零空间。如果没有,那你就完蛋了。

C++ 标准 #9.2(12) 说“以后的成员在类对象中具有更高的地址”,而 #9(4) 说“结构是类 ...”,因此,除非 C 标准在这方面有所不同尊重,它不占用零空间:在 之后有填充person_name,可能到下一个 4 字节边界(编译器和 #pragma- 和选项相关)。

你可以通过

struct foo f;
assert(&f.person_name == &f.product_name);
于 2013-05-16T01:42:10.837 回答
0

好的,所以要回答您的问题“我想知道这是否是正确的用法”,这很难说,因为零大小的数组是非标准的(尤其是在它们之后的成员)。在 c99 中,它们是使用“灵活数组成员”的标准,您只需省略数字并转到 product_name[];

长度为零的数组

但是,这将您的代码与 c99 联系在一起,最好的标准方法是简单地让您的数组长度为 1。并调整您的内存分配大小计算。显然,person_name 和 product_name 的大小都为 1 会将它们放在内存中的不同位置,但是匿名联合在 c 和 c++ 中是标准的,因此将两个数组包装在匿名联合中会使这两个数组在内存中相互重叠. 并且应该意味着您不必更改代码,因为数组的访问方式与您在示例中的方式相同。

为什么 C++ 不允许匿名结构和联合? (注意评论表明工会是合法的)

struct foo {

    int id_num;
    bool is_person;
    union
    {
        char person_name[1];
        char product_name[1];
    };

}foo;

struct foo *data = (struct foo*)malloc(sizeof(struct foo) - sizeof(char) + NAME_SIZE * sizeof(char));
于 2013-05-16T02:15:40.123 回答