我正在实现类my_unique_ptr
,my_shared_ptr
并且模仿了标准库的智能指针std::unique_ptr
,std::shared_ptr
以更好地了解它。
在实现析构函数时,我很难决定是使用内存delete
还是delete[]
释放内存。正如我在SO和其他网站上所读到的一样,没有一种可移植的方式来知道分配了多少个字节new[]
(或是否new
使用了或new[]
)(新分配了多少个字节?)
在实现类时,my_unique_ptr
我无法知道用户将向构造函数请求多少字节,即
他是否会做 my_unique_ptr<int> ptr1(new int)
还是他会做 my_unique_ptr<int> ptr1(new int[5])
如果有办法,请告诉我!
这是我的类(简化后没有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说,valgrind
在使用delete
各处而不是在构造器中delete[]
传递并传递多个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[]
。这是您的图书馆用户必须遵守的合同。如果不尊重,那就是UB。
通过提供等价物帮助用户遵守此合同std::make_unique
。另请参见使用std :: make_unique优于new运算符的优势
这是否意味着删除成功释放了new []分配的所有5个整数?
不能。调用delete
不是从new
UB获得的内存。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句