0

我正在寻找关于为什么会中断的输入。有关上下文信息,请参阅附录,但我认为这并不相关。

我有一个std::vector<uint16_t> depth_buffer初始化为 640*480 的元素。这意味着它占用的总空间是640*480*sizeof(uint16_t) = 614400

破坏的代码:

void Kinect360::DepthCallback(void* _depth, uint32_t timestamp) {
    lock_guard<mutex> depth_data_lock(depth_mutex);

    uint16_t* depth = static_cast<uint16_t*>(_depth);
    std::copy(depth, depth + depthBufferSize(), depth_buffer.begin());/// the error
    new_depth_frame = true;
}

wheredepthBufferSize()将返回 614400 (我已经验证过多次)。

我的理解std::copy(first, amount, out)first指定开始复制的内存地址,复制到amount的字节数,以及开始复制到的内存地址out

当然,它可以通过类似的方式手动完成

#pragma unroll
for(auto i = 0; i < 640*480; ++i) depth_buffer[i] = depth[i];

而不是调用std::copy,但我真的很困惑为什么std::copy在这里失败。有什么想法吗???


附录:上下文是我正在编写一个继承自的派生类FreenectDevice以使用 Kinect 360。官方错误是 a Bus Error,但我几乎可以肯定这是因为 libfreenect 将错误解释DepthCallback为 a Bus Error。逐步通过lldb,这是一个标准runtime_error被抛出std::copy。如果我手动输入depth + 614400它会崩溃,但如果我有depth + (640*480)它会突然出现。在这个阶段,我没有对深度数据做任何有意义的事情(使用 OpenGL适当地渲染原始深度是一个单独的问题 xD),所以很难判断是所有内容都被复制了,还是只是一部分。也就是说,我几乎可以肯定它并没有抓住一切。

VideoCallback与对应的和里面的调用对比copy(video, video + videoBufferSize(), video_buffer.begin()),我不明白为什么上面会崩溃。如果我的理解std::copy是错误的,这也应该崩溃,因为videoBufferSize()要返回640*480*3*sizeof(uint8_t) = 640*480*3 = 921600。这*3是因为我们uint8_t每个像素有 3 个,RGB(没有 A)。正如 OpenGL 所验证的VideoCallback那样,工作流畅(事实上它与 libfreenect 提供的示例基本相同......)。仅供参考,我发现的所有样本都没有直接与原始深度数据一起使用,它们都对深度进行着色并使用std::vector<uint8_t>RGB 通道,这不适合我对这个项目的需求。


我很高兴忽略它并在某种意义上继续前进,因为我可以让它工作,但我真的很困惑为什么会中断。感谢您的任何想法!

4

1 回答 1

1

工作方式std::copy是您提供输入序列的起点和终点以及开始复制到的位置。您提供的终点不在序列的末尾,因为您的depthBufferSize函数以字节为单位给出偏移量,而不是序列中的元素数。

如果删除乘以sizeof(uint16_t),它将起作用。此时,您也可以考虑std::copy_n改为调用,它需要复制元素的数量。

编辑:我刚刚意识到我没有直接回答这个问题。根据我对 的理解std::copy,它不应该用你给它的输入抛出异常。该代码中唯一可能引发 runtime_error 的是互斥锁的锁定。考虑到由于耗尽缓冲区末尾而导致您有未定义的行为,我很想说这与它有关。

于 2015-08-04T10:20:02.267 回答