【发布时间】:2014-02-19 01:55:45
【问题描述】:
我正在使用这个辅助函数将不同的数据类型打包到一个缓冲区中:
template <class T>
static inline void PushBack(T& value, void*& buffer) {
T* typedBuffer = (T*)buffer;
memcpy(buffer, &value, sizeof(value));
typedBuffer++;
buffer = typedBuffer;
}
我正在使用 12B 和 16B 向量(3 或 4 个浮点数)进行循环调用,它工作正常。
但是,我的其他方法没有:
template <class T>
static inline void PushBack(T& value, void*& buffer) {
T* typedBuffer = (T*)buffer;
memcpy((T*)buffer, &value, sizeof(value)); //crash on 16B
typedBuffer++;
buffer = typedBuffer;
}
template <class T>
static inline void PushBack(T& value, void*& buffer) {
T* typedBuffer = (T*)buffer;
memcpy(typedBuffer, &value, sizeof(value)); //crash
typedBuffer++;
buffer = typedBuffer;
}
template <class T>
static inline void PushBack(T& value, void*& buffer) {
T* typedBuffer = (T*)buffer;
*typedBuffer = value; //crash
typedBuffer++;
buffer = typedBuffer;
}
这三个示例在复制 16B 值时总是崩溃,之前使用 EXC_BAD_ACCESS (EXC_I386_GPFLT) 复制了 36B 的总量。
这是在 intel 上运行并编译为发布版(最快,最小)。我还不能检查程序集中发生了什么。
当我只复制 16B 向量时,问题不会发生,所以我认为这与指针未与 16B 对齐的事实有关。我可以在最后一种情况下理解它(通过指针复制),但为什么它在 memcpy 中很重要?
【问题讨论】:
-
你能构建一个完整的测试用例来证明这一点吗?
-
我正在努力。提取到其他项目似乎可以正常工作。
-
矢量是什么意思?一个例子会有所帮助。对于具有非平凡内存布局的类型,使用 memcpy 是未定义的行为。
-
它是包含 3 或 4 个浮点数的结构。我没有注意到其中一个结构请求对齐 - 我在解析其定义中的宏后找到了它。所以 - 毕竟这没什么特别的 - 隐藏对齐导致崩溃。