【发布时间】:2015-10-27 15:42:00
【问题描述】:
我有以下工会:
union problem {
int i;
int *v;
};
在我的系统上,int 是 4 个字节,而 int* 是 8 个字节。我有一个由 10 个这样的结构组成的数组。在某段代码中,我碰巧知道数组的所有成员都在使用联合的int。我需要将这些整数复制到一个整数数组中。现在,如果源数组是一个 int 数组,我可以使用 memcpy 快速复制数据。
是否可以保证 int 存储在联合的低内存或高内存中?我希望能够在不迭代的情况下复制数据,所以我正在考虑使用 SIMD 和随机播放进行循环。要做到这一点,我必须知道 int 在联合中的实际位置,我猜这是特定于实现的。
【问题讨论】:
-
不,C 规范不保证。这是一个联合,这意味着成员
i和成员v都从相同的内存位置开始。problem的总大小将取决于任何联合成员的最大大小加上完成的任何填充。memcpy()有它的用途,但这不是其中之一。最好遍历数组并分配每个数组。还做一个memcpy()也在内存区域上进行迭代。 -
我很好奇,当数组只有 10 个左右的元素并且一个简单的循环可以解决问题并且您可以移动时,为什么要优化联合数组的特定成员的复制做别的事。
-
@RichardChambers:关于成员存储在联合的表示中的 where 有保证,而不是
int和指针的位如何对应价值。 -
@RichardChambers 10 只是一个例子,因为讨论起来并不重要。但实际上它是一系列长度在 20 到 200 之间的 100-20000 个数组。可能值得返回并重写结构以避免联合并向其他结构添加更多字段。工会的选择是一个早期的设计决定,以减少逻辑或其他东西(当时这似乎是合理的)。现在看来是不明智的。
-
@R.. 我看不出你写的和我写的有什么区别。一般规则是你知道它们从哪里开始,然后你真正可以指望的是为联合分配的任何内存区域,无论是在堆栈上还是在堆上,或者任何地方都足够大以包含任何特定的成员工会。我看到很多错误是由于人们假设他们可以依靠特定的对齐方式,尤其是在涉及未明确指定成员对齐方式的结构的联合中。