使用deallocator& shared_ptr中的allocator

时间:2012-02-23 22:25:26

标签: c++ shared-ptr smart-pointers

我正在使用很少的库函数来返回使用malloc或new创建的指针。 因此,我根据使用的分配类型拥有自己的客户解除分配器。

E.g

shared_ptr<int> ptr1(LibFunctA(), &MallocDeleter); //LibFunctA returns pointer created using malloc
shared_ptr<int> ptr2(LibFunctB(), &newDeleter);  //LibFunctB returns pointer created using new

现在,我理解这是对上面的deallocator的一种非常天真的用法,但是它还有很多其他场景?

另外,如何使用客户分配器?我尝试分配如下的自定义分配器,但现在我如何实际调用它?这种功能在哪里有帮助?

shared_ptr<int> ptr3(nullptr_t, &CustomDeleter, &CustomAllocator);  //assume both functs are defined somewhere.

3 个答案:

答案 0 :(得分:6)

我没有看到任何关于以这种方式使用删除的“天真”。毕竟这是这个功能的主要目的;销毁未使用标准C ++方法分配的指针对象。

分配器适用于需要控制如何分配和删除shared_ptr的内存控制块的情况。例如,您可能有一个内存池,您希望这些内容来自,或者如果您处于内存有限的情况下,通过new分配内存是不可接受的。由于控制块的类型最多为shared_ptr,因此除了使用某种分配器之外,没有其他方法可以控制它的分配方式。

答案 1 :(得分:3)

shared_ptr的自定义删除器对于包装一些(通常)C资源非常有用,以后需要调用一个释放函数。例如,您可能会执行以下操作:

shared_ptr<void> file(::CreateFileW(...), ::CloseHandle);

这样的例子在C库中比比皆是。这节省了以后必须手动释放资源并处理可能的异常和其他恶意行为。

答案 2 :(得分:1)

我认为自定义分配器将用于为“共享计数”对象分配空间,该对象存储deallocator(删除器)和引用计数器的副本。

关于自定义删除器可以用于什么......

已经提到过一种用法:make shared_ptr与必须由某些特殊函数删除的对象兼容(如FILE删除fclose),而不必将其包含在内一个辅助类,负责正确的删除。

自定义删除器的另一个用途是池。该池可以分发用“特殊”删除器初始化的shared_ptr<T>,它不会真正删除任何内容,而是将对象返回到池中。

还有一件事:删除器已经是实现某些shared_ptr功能所必需的。例如。删除的类型始终在创建时固定,并且与正在初始化的shared_ptr的类型无关。

您可以使用shared_ptr<Base>实际初始化Derived来创建shared_ptrDerived保证在删除对象时,即使Base 没有虚拟dtor,它也会被shared_ptr删除。为了实现这一点,{{1}}已经必须存储有关如何删除对象的一些信息。因此,允许用户指定一个完全自定义的删除器不会花费任何成本(就运行时性能而言),也不需要额外的代码。

可能有很多其他场景可以很好地利用自定义删除器,这就是我到目前为止所提出的。