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

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

推荐答案

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

  • 您所描述的不满足"公共初始序列"规则的标准,因为这是关于具有 struct 类型的unions 成员的.指针不是 struct .

  • 即使我们讨论的是包含指针作为成员的 struct ,如果指针指向的类型不兼容,则指针类型也不兼容. voidlong是不兼容的类型,Foo可能也不兼容,所以即使你把指针包装在 struct 中,公共初始序列规则也不适用.

  • 在C语言中,您不需要依赖公共初始序列规则来读取与上次编写的联合成员不同的联合成员.在实践中,实现对所有对象指针类型使用相同的表示形式是非常常见的,在这样的实现中,您可能可以使用这些指针成员中的任何一个来释放指向的数据.然而,C并不是所有的对象指针类型都使用相同的表示形式,历史上也有这样的实现.在其中一种实现中,您所描述的实践很可能不会像您希望的那样可靠地运行.这样的代码可以符合语言规范,但它不符合strictly.它不能随身携带.

C++相关问答推荐

需要大整数和浮点数.使用long long int和long double

由Go调用E.C.引起的内存快速增长

当打印字符串时,为什么在c中没有使用常量限定符时我会收到警告?

使用NameSurname扫描到两个单独的字符串

堆栈在作用域阻塞后会被释放吗?

拥有3x3二维数组并访问数组[1][3]等同于数组[2][0]?

在C语言中,在数学运算过程中,为什么浮点数在变量中的行为不同

平均程序编译,但结果不好

如何在下面的C代码中正确管理内存?

用gcc-msse 2编译的C程序包含AVX 1指令

不同出处的指针可以相等吗?

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

在C中包装两个数组?

使用ld将目标文件链接到C标准库

c程序,让用户输入两类数字,并给出输出用户输入多少个数字

从Raku nativecall调用时精度不同

如何解释数组中的*(ptr)和*(ptr+2)?

在C中打印指针本身

在C中,为什么这个带有递增整数的main函数从不因溢出而崩溃?

使用复合文字数组初始化的指针数组