c语言 - 为一个联盟分配足够的内存只给一个成员是错误的吗?



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

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

相关内容

  • 没有找到相关文章

最新更新