修改 std pmr 向量的内部元素
Modifying inner elements of std pmr vector
如果我理解得很好,std::pmr::vector<std::pmr::string>
应该使用相同的底层 std::pmr::memory_resource
假设我们有接近
的东西
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");
那么假设vector内存块是256字节宽,两个长字符串会在vector内存块之后分配。
现在,让我们假设我们对矢量再做一次 push_back
。
如果当前容量不够,我们将重新分配一切。这对我来说似乎很公平。
所以实际上,我们一次只有一个大内存块。 (由矢量块和2个长字符串组成)
现在假设我们通过 vector[0] = getLongString()
.
之类的操作来更改第一个 "short_string"
如果内存资源还有地方在里面,当我们调用分配函数时,它会returns一个指向有效地址的指针,没有任何问题。但是,让我们假设内存资源对象不再有任何 space。有几种可能:
- 内存资源抛出异常:我们只保留一个大内存块
- 内存资源刚刚分配新的space(例如从堆中分配)并且字符串现在分配在另一个地方而不是分配的第一个内存块:我们有2个大内存块(1个由向量和一些字符串,其中一个仅由新的大字符串组成)
- 内存资源分配新的 space,并告诉向量(通过魔法?)使用这个新的大块重新分配所有内容。
我认为只有 1 和 2 是正确的,但我不确定。第三种可能吗?
不允许选项 3。
分配器不知道它分配的内存是如何使用的。对于每个请求,它得到的只是 std::size_t bytes, std::size_t alignment
。重新分配向量会使指针、引用和迭代器失效。
MyMemoryResource
需要有一个策略来处理所有可能的 do_allocate
调用序列。它要么永远分配内存,要么在某些情况下抛出。
如果我理解得很好,std::pmr::vector<std::pmr::string>
应该使用相同的底层 std::pmr::memory_resource
假设我们有接近
的东西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");
那么假设vector内存块是256字节宽,两个长字符串会在vector内存块之后分配。
现在,让我们假设我们对矢量再做一次 push_back
。
如果当前容量不够,我们将重新分配一切。这对我来说似乎很公平。
所以实际上,我们一次只有一个大内存块。 (由矢量块和2个长字符串组成)
现在假设我们通过 vector[0] = getLongString()
.
"short_string"
如果内存资源还有地方在里面,当我们调用分配函数时,它会returns一个指向有效地址的指针,没有任何问题。但是,让我们假设内存资源对象不再有任何 space。有几种可能:
- 内存资源抛出异常:我们只保留一个大内存块
- 内存资源刚刚分配新的space(例如从堆中分配)并且字符串现在分配在另一个地方而不是分配的第一个内存块:我们有2个大内存块(1个由向量和一些字符串,其中一个仅由新的大字符串组成)
- 内存资源分配新的 space,并告诉向量(通过魔法?)使用这个新的大块重新分配所有内容。
我认为只有 1 和 2 是正确的,但我不确定。第三种可能吗?
不允许选项 3。
分配器不知道它分配的内存是如何使用的。对于每个请求,它得到的只是 std::size_t bytes, std::size_t alignment
。重新分配向量会使指针、引用和迭代器失效。
MyMemoryResource
需要有一个策略来处理所有可能的 do_allocate
调用序列。它要么永远分配内存,要么在某些情况下抛出。