只为一个成员分配足够的内存给联合是错误的吗?
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;
}
是否可以分配足以容纳特定联合成员的内存?我的意思是这样的:
#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;
}