C++ 我是否需要一个用于共享\u ptr的删除程序来释放分配器分配的内存?
我想使用shared_ptr来管理动态分配的阵列。在我了解STL分配器的存在之前,我总是使用new[]来分配内存,并为shared_ptr编写一个deleter来释放内存。然后,代码将如下所示: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
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
是平凡的),则这具有未定义的行为
出于同样的原因,对于自定义分配器,您的代码也不一定正确