我对使用union感到困惑,我尝试了不同的方法来访问它失败了。一个例子:
union
{
struct
{
char cycle;
char freq;
char id;
} Umember_a;
char Umember_b[3];
} data_u;
char info[3];
我想复制" info"数组到联合" data_u",但是如果我使用以下任何一个,我发现有错误:
memcpy(data_u, info, sizeof(data_u));
memcpy(&data_u, info, sizeof(data_u));
memcpy(data_u.Umember_a, info, sizeof(data_u));
memcpy(data_u.Umember_a, info, sizeof(data_u.Umember_a));
但我可以使用:
memcpy(data_u.Umember_b, info, sizeof(data_u.Umember_b));
memcpy(&data_u.Umember_a, info, sizeof(data_u.Umember_a);
你能帮我解释一下吗?
答案 0 :(得分:4)
不幸的是,这种方法注定要失败,因为您假设cycle
,freq
和id
紧密地包含在结构中。情况不一定如此:编译器可以自由选择任何方式对齐结构成员。
您可以使用info
将Umember_b
复制到memcpy
。这将是安全的,因为(i)保证阵列是连续的,并且(ii)Umember_b[0]
的地址将与data_u
的地址相同。但是你不知道memcpy
如何在Umember_a
的元素中分配自己。
有些编译器允许您更改结构包装,但这根本不够便携,不可靠。
答案 1 :(得分:0)
显然你不能做memcpy(data_u, info, sizeof(data_u));
之类的事情,因为memcpy需要一个指针,但你传递一个变量。这与工会无关。将指针传递给memcpy 的情况不应该给出错误。因为在C中,任何指针都可以隐式地转换为void*
/从memcpy(&data_u, info, sizeof(data_u));
转换。如果你在这里收到错误,那是因为你错误地将你的C代码编译为C ++,它有更严格的类型要求。
memcpy(data_u.Umember_b, info, 3);
将起作用,但严格来说这会破坏C的别名规则。特别是因为C struct / union可能包含填充字节。无论你打算如何处理这个联盟,都需要考虑填充。
{{1}}是最安全,最正确的方法。它是否真的有效取决于是否有填充。