我正在寻找输入原因。有关上下文信息,请参阅附录,但我并不认为它是相关的。
我有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;
}
其中depthBufferSize()
将返回614400(我已经多次验证了这一点)。
我对std::copy(first, amount, out)
的理解是first
指定了开始复制的内存地址,amount
是复制的字节数,以及{ {1}}是开始复制到的内存地址。
当然,可以通过
等手动完成out
而不是对#pragma unroll
for(auto i = 0; i < 640*480; ++i) depth_buffer[i] = depth[i];
的调用,但我真的很困惑为什么std::copy
在这里失败了。任何想法???
附录:上下文是我正在编写一个派生类,它继承自std::copy
以使用Kinect 360.正式错误是FreenectDevice
,但我几乎可以肯定这一点是因为libfreenect将Bus Error
中的错误解释为DepthCallback
。单步执行Bus Error
,它是从lldb
抛出的标准runtime_error
。如果我手动输入std::copy
它会崩溃,但如果我有depth + 614400
它将会突然出现。在这个阶段,我没有对深度数据做一些有意义的事情(使用OpenGL正确渲染原始深度 是一个单独的问题xD),因此很难判断是否所有被复制,或只是一部分。也就是说,我几乎是肯定的,它并没有抓住它。
与相应的depth + (640*480)
和VideoCallback
内部的调用相比,我不明白为什么上述情况会崩溃。如果我对copy(video, video + videoBufferSize(), video_buffer.begin())
的理解是错误的,那么这应该会崩溃,因为std::copy
将返回videoBufferSize()
。 640*480*3*sizeof(uint8_t) = 640*480*3 = 921600
来自于每个像素有3 *3
个RGB RGB(无A)这一事实。 uint8_t
游戏工作,正如OpenGL验证的那样(事实上它与libfreenect提供的样本基本相同......)。仅供参考我发现的样本中没有一个实际上直接使用原始深度数据,所有样本都会着色深度并使用带有RGB通道的VideoCallback
,这不符合我对此项目的需求。
我很高兴只是忽略它并在某种意义上继续前进,因为我可以让它发挥作用,但我真的很困惑为什么这会破坏。谢谢你的任何想法!
答案 0 :(得分:1)
std::copy
的工作方式是提供输入序列的起点和终点以及开始复制的位置。您提供的结束点不在序列的末尾,因为您的depthBufferSize
函数提供了以字节为单位的偏移量,而不是序列中的元素数量。
如果您将乘以sizeof(uint16_t)
,则会有效。此时,您可能还会考虑调用std::copy_n
,这需要复制元素的数量。
编辑:我刚才意识到我没有直接回答这个问题。
根据我对std::copy
的理解,它不应该通过您提供的输入抛出异常。该代码中唯一可以抛出runtime_error的是锁定互斥锁。
考虑到你的缓冲区结束后你有未定义的行为,我很想说它与它有关。