在C中结构的末尾有两个零长度数组成员

时间:2013-05-16 00:38:05

标签: c data-structures unions

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

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

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

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

好的,那么回答你的问题“我想知道这是否是一个正确的用法”,很难分辨,因为零大小的数组是非标准的(尤其是在它们之后的成员)。在c99中,他们使用“灵活的阵列成员”是标准的,您只需省略号码并转到product_name [];

Array of zero length

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

Why does C++ disallow anonymous structs and unions? (注释评论表明工会是合法的)

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