只为一个成员分配足够的内存给联合是错误的吗?

Is it wrong to allocate enough memory to a union for just one member?

是否可以分配足以容纳特定联合成员的内存?我的意思是这样的:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

union u;

union u{
    int a;
    long b[4096];
};

int main(){
    union u tmp = {.a = 42};
    union u *u = (union u*) malloc(sizeof(int)); //not malloc(sizeof(union u))
    memcpy(u, &tmp, sizeof(int));
    printf("u::a = %lu\n", u -> a);
}

sizeof(union u) 等于 sizeof(long[4096]),分配 4096 * sizeof(long) 来保存单个 int.

会浪费内存

有没有可能像上面那样做?还是未定义的行为?

我找到了为什么联合使用无效的答案。 N1570::6.2.5p(20):

A union type describes an overlapping nonempty set of member objects, each of which has an optionally specified name and possibly distinct type.

这意味着联合对象必须分配足够的内存来容纳联合的每个成员,但它是重叠的。在我的例子中,联合的使用是不合法的,因为我分配的内存足以容纳其中一个。

Is it possible to allocate memory that's enough to hold only a specific union member?

是的。然而,代码不得尝试使用未分配部分中的成员。


为清楚起见,以下使用 union ab 而不是 union u

代码的初始部分:没有问题。

#include <stdio.h>
#include <string.h>
#include <malloc.h>

union ab;

union ab {
    int a;
    long b[4096];
};

int main(){
    union ab tmp = {.a = 42};

分配指向不足内存的指针本身不是问题。虽然不需要 for cast,但我发现分配给 object/member 的大小比分配给类型的大小更能提供信息(更容易编码、审查和维护)。

    // union ab *u = (union ab*) malloc(sizeof(int)); //not malloc(sizeof(union ab))
    union ab *u = malloc(sizeof u->a);

copying/assignment没有问题,因为u指向的内存足够

    memcpy(u, &tmp, sizeof(int));
    // or 
    u.a = tmp.a;

打印是一个问题,因为代码使用了不匹配的说明符。在更正后的代码中,访问成员 .a

没有问题
    // printf("ab::a = %lu\n", u -> a);
    printf("ab::a = %d\n", u->a);

到目前为止没有问题。

一些新代码是一个问题,因为代码试图通过 u 读取分配内存之外的内容 - 这是 未定义的行为 (UB)。

    temp = *u;
}