2

I have a std::vector<unsigned char> vec and a pre-allocated contiguous buffer of (unsigned char) with size (len), that I know it's beginning which is stored in an unsigned char* variable named start. I know I can use std::copy(start,start+len,vec.begin()) to copy them into the vector, but can I do that without copying? Can I make vec.begin() point to start pointer? I have all the values already allocated in memory, and I do not want to have to copy them into the vector because I have a memory constraint.

The pointer and length are given to me via an external API, so I cannot change that.

Justin
  • 24,288
  • 12
  • 92
  • 142
Aref
  • 59
  • 1
  • 5
  • 2
    could you give us some code to work from? It sounds like you might want a [`span`](https://github.com/Microsoft/GSL/blob/master/include/gsl/span) or `view` instead. – jaggedSpire Jul 28 '17 at 22:00
  • Note that `std::copy(start,start+len,vec.begin())` is undefined behaviour if you haven't already done `vec.resize(len)`. – Justin Jul 28 '17 at 22:02
  • 1
    Just stick with the `std::vector` constructor. Like this: `std::vector vec (start, start + len);` – DimChtz Jul 28 '17 at 22:04
  • 1
    @DimChtz Note that that does allocate the extra memory – Justin Jul 28 '17 at 22:05
  • 3
    This might be doable by hacking custom allocators in some very, very sketchy ways. However, this is really gross. Better solutions are: 1) just suck it up and copy into the vector. Is it really the end of the world to do this? 2) Give up on having a vector. The canonical way in C++ to pass this sort of thing is through pairs of iterators and this example actually illustrates why. – Nir Friedman Jul 28 '17 at 22:05

2 Answers2

7

There is no interface into vector to make it take ownership of your pre-existing buffer. Even if you could shoe-horn it into the vector by using a custom allocator that provides this memory's address, the vector will consider it raw memory and overwrite it.

If it must be a vector, then you're out of luck without copying.

However, some sort of adaptive view on the existing buffer could give a container-like interface over your array without copying (such as the gsl::span as suggested in comments by Justin.)

gsl::span<int> s(myPtr, 4);

see https://github.com/Microsoft/GSL and http://codexpert.ro/blog/2016/03/07/guidelines-support-library-review-spant/

Chris Uzdavinis
  • 6,022
  • 9
  • 16
  • This would be a good answer on the duplicate target (naturally, you'd have to make sure it is rewritten to fit the context of it) – Justin Jul 28 '17 at 22:36
  • Microsoft has an `array_view` class, and there is a proposal for a `std::array_view` class to be added to the standard STL. – Remy Lebeau Jul 28 '17 at 23:54
0

Since you want to control the memory allocation of your vector, you will need to create your own allocator class to do that, and pass it as a template parameter like this :

std::vector<int, my_custom_allocator<int>> my_vector;

Here is a good tutorial on how to create your own allocator : The Standard Librarian: What Are Allocators Good For?

HatsuPointerKun
  • 637
  • 1
  • 5
  • 14