是否可以分配足以容纳特定工会成员的内存?我的意思是这样的:
#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 = %lun", u -> a);
}
sizeof(union u)
等于sizeof(long[4096])
,分配4096 * sizeof(long)
来保存单个int
会浪费内存。
有没有可能做上面这样的事情?还是未定义的行为?
我找到了为什么它是无效的联合用法的答案。N1570::6.2.5p(20)
:
联合类型描述一组重叠的非空成员对象, 每个都有可选指定的名称,并且可能不同 类型。
这意味着联合对象必须分配足够的内存来容纳联合的每个成员,但它是重叠的。就我而言,这不是合法使用联合,因为我分配的内存足以容纳其中一个。
是否可以分配足以容纳特定工会成员的内存?
是的。 但是,代码不得尝试在未分配的部分中使用成员。
为清楚起见,下面使用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};
将指针分配给内存不足本身不是问题。 尽管不需要 cast 并且我发现分配给对象/成员的大小比分配给类型的大小更有信息(更容易编码、审查和维护)。
// 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 = %lun", u -> a);
printf("ab::a = %dn", u->a);
到目前为止没有问题。
一些新代码是一个问题,因为代码试图通过u
读取,在分配的内存之外 - 这是未定义的行为(UB)。
temp = *u;
}