C++ 我是否需要一个用于共享\u ptr的删除程序来释放分配器分配的内存?

C++ 我是否需要一个用于共享\u ptr的删除程序来释放分配器分配的内存?,c++,memory,stl,C++,Memory,Stl,我想使用shared_ptr来管理动态分配的阵列。在我了解STL分配器的存在之前,我总是使用new[]来分配内存,并为shared_ptr编写一个deleter来释放内存。然后,代码将如下所示: struct ArrayDeleter { void operator()(int* p) { delete [] p; } }; ... ... std::shared_ptr<int> array(new int[100], ArrayDeleter()); ... std::a

我想使用shared_ptr来管理动态分配的阵列。在我了解STL分配器的存在之前,我总是使用new[]来分配内存,并为shared_ptr编写一个deleter来释放内存。然后,代码将如下所示:

struct ArrayDeleter
{
   void operator()(int* p) { delete [] p; }
};
...
...
std::shared_ptr<int> array(new int[100], ArrayDeleter());
...
std::allocator<int> alloc;
std::shared_ptr<int> array(alloc.allocate(10));
...
因此,代码中没有提供特定的删除器。然后我用valgrind检查了这个程序,但是这次,它没有任何抱怨。因此,我可以安全地假设std::allocator实现为使用
new
分配内存,这样std::shared\u ptr使用的默认
delete
操作符就可以了吗

那我实现自己的分配器呢?不使用新运算符的自定义分配器会破坏上述代码,即我仍然需要删除器,这是对的吗

我可以安全地假设std::allocator实现为使用新的 分配内存,以便 std::shared_ptr可以吗

不,你不能。默认的
std::allocator
被定义为使用global
::operator new
分配内存,但我认为不需要每次调用
allocate
都只导致一次调用
::operator new
,或者从
allocate()返回的值
等于从
new
返回的值

释放内存的正确方法是在分配器上调用
deallocate()
,它将使用全局
::operator delete

因此,您的代码没有正确释放数据。在您的实现中,
std::allocator
对分配没有做任何特殊的处理,在
int*
上调用
delete
的行为与调用全局操作符
delete
的行为相同。对于其他类型或其他实现,它可能会失败

另外,
allocate()
不会初始化对象,因此调用
delete
会调用一些从未构造过的内存的析构函数。如果类型不是平凡的(
int
是平凡的),则这具有未定义的行为

出于同样的原因,对于自定义分配器,您的代码也不一定正确

我可以安全地假设std::allocator实现为使用新的 分配内存,以便 std::shared_ptr可以吗

不,你不能。默认的
std::allocator
被定义为使用global
::operator new
分配内存,但我认为不需要每次调用
allocate
都只导致一次调用
::operator new
,或者从
allocate()返回的值
等于从
new
返回的值

释放内存的正确方法是在分配器上调用
deallocate()
,它将使用全局
::operator delete

因此,您的代码没有正确释放数据。在您的实现中,
std::allocator
对分配没有做任何特殊的处理,在
int*
上调用
delete
的行为与调用全局操作符
delete
的行为相同。对于其他类型或其他实现,它可能会失败

另外,
allocate()
不会初始化对象,因此调用
delete
会调用一些从未构造过的内存的析构函数。如果类型不是平凡的(
int
是平凡的),则这具有未定义的行为

出于同样的原因,对于自定义分配器,您的代码也不一定正确