I'm looking for input as to why this breaks. See the addendum for contextual information, but I don't really think it is relevant.
I have an std::vector<uint16_t> depth_buffer
that is initialized to have 640*480 elements. This means that the total space it takes up is 640*480*sizeof(uint16_t) = 614400
.
The code that breaks:
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;
}
where depthBufferSize()
will return 614400 (I've verified this multiple times).
My understanding of std::copy(first, amount, out)
is that first
specifies the memory address to start copying from, amount
is how far in bytes to copy until, and out
is the memory address to start copying to.
Of course, it can be done manually with something like
#pragma unroll
for(auto i = 0; i < 640*480; ++i) depth_buffer[i] = depth[i];
instead of the call to std::copy
, but I'm really confused as to why std::copy
fails here. Any thoughts???
Addendum: the context is that I am writing a derived class that inherits from FreenectDevice
to work with a Kinect 360. Officially the error is a Bus Error
, but I'm almost certain this is because libfreenect interprets an error in the DepthCallback
as a Bus Error
. Stepping through with lldb
, it's a standard runtime_error
being thrown from std::copy
. If I manually enter depth + 614400
it will crash, though if I have depth + (640*480)
it will chug along. At this stage I am not doing something meaningful with the depth data (rendering the raw depth appropriately with OpenGL is a separate issue xD), so it is hard to tell if everything got copied, or just a portion. That said, I'm almost positive it doesn't grab it all.
Contrasted with the corresponding VideoCallback
and the call inside of copy(video, video + videoBufferSize(), video_buffer.begin())
, I don't see why the above would crash. If my understanding of std::copy
were wrong, this should crash too since videoBufferSize()
is going to return 640*480*3*sizeof(uint8_t) = 640*480*3 = 921600
. The *3
is from the fact that we have 3 uint8_t
's per pixel, RGB (no A). The VideoCallback
works swimmingly, as verified with OpenGL (and the fact that it's essentially identical to the samples provided with libfreenect...). FYI none of the samples I have found actually work with the raw depth data directly, all of them colorize the depth and use an std::vector<uint8_t>
with RGB channels, which does not suit my needs for this project.
I'm happy to just ignore it and move on in some senses because I can get it to work, but I'm really quite perplexed as to why this breaks. Thanks for any thoughts!
The way std::copy
works is that you provide start and end points of your input sequence and the location to begin copying to. The end point that you're providing is off the end of your sequence, because your depthBufferSize
function is giving an offset in bytes, rather than the number of elements in your sequence.
If you remove the multiply by sizeof(uint16_t)
, it will work. At that point, you might also consider calling std::copy_n
instead, which takes the number of elements to copy.
Edit: I just realised that I didn't answer the question directly.
Based on my understanding of std::copy
, it shouldn't be throwing exceptions with the input you're giving it. The only thing in that code that could throw a runtime_error is the locking of the mutex.
Considering you have undefined behaviour as a result of running off of the end of your buffer, I'm tempted to say that has something to do with it.