如果容器和分配器都是同一内存池的一部分,我还需要调用std::容器的析构函数吗?

Do I still need to call a destructor of a std::container if both the container and allocator are part of the same memory pool?

本文关键字:调用 std 析构函数 分配器 内存 一部分 如果      更新时间:2023-10-16

(以使用线程构建块内存池为例)

假设我有以下设置:

using MemoryPool = tbb::memory_pool<std::allocator<char>>;
using CustomAllocator = tbb::memory_pool_allocator<Result*>;
using CustomVector = std::vector<Result*, CustomAllocator>;
MemoryPool shortTermPool;
void* allocatedMemory = shortTermPool.malloc(sizeof(CustomVector);
CustomVector* results = static_cast<CustomVector*>(allocatedMemory);
new(results) CustomVector(CustomAllocator(shortTemPool));

之后我调用

shortTermPool.recycle(); 

这行代码回收了内存池中的所有内存,允许我重用它。现在,由于vector和它的分配器都在使用内存池,我还需要调用

吗?
results->~vector();

在回收内存池之前?析构函数是否做了任何额外的工作,或者回收整个池是否足够?

来自c++标准:

3.8对象生存期

4程序可以通过重用该对象所占用的存储空间或显式地终止该对象的生命周期使用非平凡析构函数调用类类型对象的析构函数。对于具有非平凡析构函数的类类型的对象函数之前显式调用析构函数是不需要的对象占用的存储空间被重用或释放;然而,如果没有显式调用析构函数,也没有delete表达式(5.3.5)不能用于释放存储,析构函数也不能被隐式调用和任何依赖于副作用的程序析构函数产生的行为是未定义的。

它取决于std::vector析构函数是否是非平凡的并且具有程序所依赖的副作用。因为它是一个标准库类,为了安全起见,建议调用析构函数。否则,你必须检查std::vector的实现,现在和将来所有你希望你的代码兼容的标准库。
如果vector类是你自己的,你就可以控制析构函数的实现,如果析构函数无关紧要,或者没有程序所依赖的副作用,就可以忽略调用它,如上所述。