C语言 指向不同类型的指针是否符合“公共初始序列”规则?

ymzxtsji  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(212)

如果我有一个包含指向不同类型数据的指针的联合体,那么通过一个与它被分配的字段不同的字段来释放错误的内存是法律的吗?它甚至符合“公共初始序列”规则吗?

#include <stdlib.h>

typedef struct {
    int type;
    union {
        void *entries;
        long *long_entries;
        // etc
    } u;
} Bar;

int main (void) {
   Bar bar;
   bar.u.long_entries = malloc(6 * sizeof(long));
   free(bar.u.entries);
}

字符串
我倾向于说这是法律的,但我不完全确定。
考虑到目前为止的答案,我认为我必须将我的代码更改为这样的代码;我希望这是完全法律的:

typedef struct {
    int type;
    void *entries;
} Bar;

int main(int argc, char *argv[]) {
    Bar bar;
    bar.entries = malloc(6 * sizeof(long));
    // ...
    long *long_entries = bar.entries;
    long_entries[3] = 123;
    // ...
    free(bar.entries);
}

vdzxcuhz

vdzxcuhz1#

如果我有一个包含指向不同类型数据的指针的联合体,那么通过一个与它被分配的字段不同的字段来释放错误的内存是法律的吗?它甚至符合“公共初始序列”规则吗?

  • 您所描述的内容不满足“公共初始序列”规则的标准,因为这是关于具有结构类型的联合成员的。指针不是结构。
  • 即使我们讨论的是包含指针作为成员的结构,如果指针指向的类型不兼容,则指针类型也不兼容。voidlong是不兼容的类型,并且可能Foo与任何一个都不兼容,因此即使将指针 Package 在结构中,公共初始序列规则也不适用。
  • 在C语言中,你不需要依赖公共初始序列规则来读取一个不同于上次写入的联合成员。在实践中,实现对所有对象指针类型使用相同的表示是非常常见的,在这样的实现中,你可能可以使用任何这些指针成员来释放指向的数据。然而,C并不要求所有的对象指针类型都使用相同的表示,历史上也有过这样的实现。在其中一个实现中,你描述的实践很可能不会像你想的那样可靠地运行。这样的代码可以符合语言规范,但它并不严格符合 *。它不是便携式的。
nafvub8i

nafvub8i2#

指向不同类型的指针是否符合“公共初始序列”规则?

通过与分配给它的字段不同的字段释放错误的内存是法律的吗?
在问题的上下文中,free(bar.entries)有效吗?
我会说这福尔斯实现依赖。当你读取一个被分配的不同的联合成员时,内存被解释为新的类型。现在,当你将存储long *的内存重新解释为void *时,你会得到一个正确的地址,它将指向同一个long *,在这种情况下,bar.entries == bar.long_entries。或者它可能不会发生。或者你可能会得到一个陷阱表示。

  • 在实践中 *,代码将在正常架构上工作,因为正常架构在汇编中表示的所有指针类型都是相同的。

相关问题