If I have a NSData* from one API and need to turn that into an std::vector for another API, is there any way to do this safely without copying the bytes in the NSData (assume a very large NSData*)?
-
You might be able to create a custom allocator (the second template parameter of `std::vector`) that does this, but I don't think there's anything out-of-the-box that would do this for you. – Adam Rosenfield May 27 '13 at 23:53
2 Answers
No quick solution that comes to mind, no.
If you create the NSData object (rather than it being returned by another API), you might consider subclassing NSData
and/or NSMutableData
when you really need to avoid the copy -- then you could access the storage (std::vector) directly.
You may also be able to sneak around it in some cases by creating the data with 'your' allocation:
NSData * data([[NSData alloc]
initWithBytesNoCopy:vector.data()
length:vector.size()
freeWhenDone:false]);
of course, you need to make sure the vector is not resized (or its backing store reallocated) before the NSData
object is deallocated.
Sometimes you also need to consider changing the parameter type so that it is not a std::vector
. A little container which has a NSData
member and a vector-like interface, iterator, or begin+end may be adequate while accommodating other collections types.

- 104,054
- 14
- 179
- 226
I don't know enough about stl or cpp, but if you can construct a vector from a void* buffer then you should be able to with:
void * buffer = [data bytes];
size_t len = [data length];
keep in mind that the data owns the buffer so you may not free it.

- 14,399
- 2
- 48
- 76