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

时间:2018-12-22 08:47:44

标签: c memory-management malloc language-lawyer unions

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

#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会浪费内存。

是否可以执行上述操作?还是未定义的行为?

2 个答案:

答案 0 :(得分:2)

我找到了答案,为什么它无效使用union。 N1570::6.2.5p(20)

  

联合类型描述了一组重叠的非空成员对象,   每个都有一个可选的指定名称,并且可能不同   类型。

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

答案 1 :(得分:1)

  

是否可以分配足以容纳特定工会成员的内存?

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


为清楚起见,下面使用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};

分配一个指向内存不足的指针本身并不是问题。尽管不需要强制转换,但我发现分配给对象/成员的大小比分配给类型的大小更有意义(更易于编码,检查和维护)。

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

复制/分配没有问题,因为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;
}