我正在实现类 my_unique_ptr
和 my_shared_ptr
模仿标准库智能指针 std::unique_ptr
和 std::shared_ptr
更好地了解它。
在实现析构函数时,我很难决定是否使用 delete
或 delete[]
释放内存。就我在 SO 和其他网站上阅读的内容而言,没有可移植的方式可以知道 new[]
分配了多少字节。 (或者是否使用了 new
或 new[]
)( How many bytes were allocated by new? )
在实现类 my_unique_ptr
时我无法知道用户将从构造函数请求多少字节,即
他会不会做my_unique_ptr<int> ptr1(new int)
或者他会做
my_unique_ptr<int> ptr1(new int[5])
如果有办法请告诉我!
这是我的类(class)(经过简化且没有 cpy/move 构造函数):
template<typename ValueType>
class my_unique_ptr {
ValueType *internal_ptr = nullptr;
public:
// Default constructor
my_unique_ptr() {
internal_ptr = nullptr;
}
// Paramterized constructor
explicit my_unique_ptr(ValueType *ptr) {
if (ptr)
internal_ptr = ptr;
}
// Destructor
~my_unique_ptr() {
// How do I know whether to use
delete ptr;
// or
delete[] ptr;
}
我在某处读到编译器会跟踪 new[]
的参数然后由 delete[]
使用正确释放内存。另请阅读“程序员有责任将 new
与 delete
和 new[]
与 delete[]
匹配”。但是我如何在我的类里面对此进行编程,以便它始终匹配正确的运算符?
旁注:
正在运行 valgrind
使用 delete
时到处而不是delete[]
并通过超过 1 int
(比如 new int[5]
)在我的构造函数中,Valgrind 说所有内存块都被释放了,没有泄漏的机会! (尽管显示类似 mismatched new[] with delete
的警告。这是否意味着 delete
成功释放了 ints
分配的所有 5 个 new[]
?请帮忙。
我在 Ubuntu 18.04
并使用 gcc 7.5.0
.
最佳答案
你是对的,你不知道内存是否由 new
分配。或 new[]
.但是你甚至不知道一个内存存储了一个自动持续时间对象。例如。您的用户可以:
int a = 24;
my_unique_ptr<int> ptr1(&a); // oups
你无法知道这一点。所以做标准库做的事情:
对数组类型进行专门化,例如
template <class T> class my_unique_ptr<T[]>
那叫delete[]
在析构函数上。要求
my_unique_ptr<T>
必须使用从new
获得的内存进行初始化和my_unique_ptr<T[]>
必须使用从new[]
获得的内存进行初始化.这是您图书馆的用户必须遵守的契约(Contract)。如果没有得到尊重,那就是 UB。通过提供
std::make_unique
的等效项来帮助用户遵守此契约(Contract).另见 Advantages of using std::make_unique over new operator
Does this mean delete is successfully freeing all the 5 ints allocated by new[]
没有。打电话delete
在不是从 new
获得的内存上是UB。
关于c++ - 如何知道何时在 C++ 中调用 delete 以及何时调用 delete[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62547716/