Home > database >  Modifying inner elements of std pmr vector
Modifying inner elements of std pmr vector

Time:03-02

If I understand things well, a std::pmr::vector<std::pmr::string> should use the same underlying std::pmr::memory_resource

Let's say we have something near to

class MyMemoryResource : public std::pmr::memory_resource{...};

std::pmr::vector<std::pmr::string> vector;

vector.push_back("short string");
vector.push_back("long long long long long long long string");
vector.push_back("long long long long long long long string");

So let's imagine the vector memory block is 256 bytes wide, the two long string will be allocated after the vector memory block.

Now, let's imagine we do another push_back to the vector. If the current capacity is not enough, we will reallocate everything. It seems to be fair to me.

So actually, we do have only one BIG memory block at a time. (which is componed by the vector block, and the 2 long string)

Now let's imagine we change the first "short_string" by doing something like vector[0] = getLongString().

If the memory resource still have place inside it, when we call the allocate function, it will returns a pointer to a valid address, without any problem. However, let's imagine the memory resource object does not have any space anymore. There is several possibilities :

  1. The memory resource just throw an exception : We keep the only one big memory block
  2. The memory resource just allocate new space (for example from the heap) and the string is now allocated on an another place than the first memory block allocated : we have 2 big memory block (1 componed by the vector and some string, and one componed only by the new big string)
  3. The memory resource allocates new space, and tell the vector (by magic ?) to reallocate everything using this new big block.

I think only the 1 and 2 are corrects, but I am not sure. Is the third possibilities possible?

CodePudding user response:

Option 3 is not permitted.

The allocator has no knowledge of how the memory it allocates is used. All it gets is std::size_t bytes, std::size_t alignment for each request. Reallocating the vector would invalidate pointers, references and iterators.

MyMemoryResource needs to have a strategy to deal will all possible sequences of do_allocate calls. Either it keeps handing out memory forever, or it throws under some circumstances.

  • Related