在c ++中调用析构函数中的delete []
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在c ++中调用析构函数中的delete []相关的知识,希望对你有一定的参考价值。
我怀疑在下面的代码中,析构函数中有一个析构函数delete line[]
,我只是想知道这个删除是否有任何堆栈溢出,这可能是对析构函数的递归调用的结果。
class Line {
public:
char *line;
Line(const char *s = 0) {
if (s) {
line = new char[strlen(s)+1];
strcpy(line, s);
} else {
line = 0;
}
}
~Line() {
delete[] line; //----------> how this delete will work?
line = 0;
}
Line &operator=(const Line &other) {
std::cout <<"go"<< endl;
delete[] line; //----------> purpose of using this delete??
line = new char[other.len()+1];
strcpy(line, other.line);
return *this;
}
int operator<=(const Line &other) {
int cmp = strcmp(line, other.line);
return cmp <= 0;
}
int len() const {
return strlen(line);
}
};
int main() {
Line array[] = {Line("abc"), Line("def"),
Line("xyz")};
Line tmp;
}
重载赋值运算符内部的删除是在分配新内存之前清理内存(我已经在某处读过它,如果我错了就纠正我),但是这个删除会调用析构函数吗?
请解释
不,它不会。
此delete语句将删除char数组。只有在销毁Line对象时才会调用Line的析构函数。然而,这不是这种情况。
变量行和对象/类Line是不同的东西。
line变量是Line类中的成员变量。所以这两个名字看起来是一样的,但完全不同。
delete[] line;
将new char[strlen(s)+1];
语句与构造函数和赋值运算符配对。请注意,如果delete[] line;
被设置为line
,nullptr
是一个无操作,这是else
分支任务所做的,尽管它使用0
代替nullptr
。
请放心,析构函数不会递归调用。只是析构函数用于释放任何已分配的内存。
但是使用std::string line;
作为类成员变量,或者甚至整个类本身都会更容易。您的代码中存在一些微妙的错误 - 自我分配就是其中之一,并且缺少复制构造函数。让C ++标准库为您处理所有这些。总之,你可以写
int main() {
std::string array[] = {"abc", "def", "xyz"};
std::string tmp;
}
delete[]
的参数是char*
,即没有调用析构函数(并且也没有析构函数的递归调用)。
如果你有这样的析构函数:
~Line() { delete this; } // DONT DO THIS !!! (also for other reasons it is not OK at all)
这会尝试递归调用自己,但你的代码看起来很好。
在赋值运算符中
line = new char[other.len()+1];
将分配新内存并将指针(指向此内存)分配给line
。这将导致您无法处理旧内存,并且为了避免泄漏,您需要先删除它。
默认情况下,C ++负责char *的delete [],因此您无需执行任何操作。
以上是关于在c ++中调用析构函数中的delete []的主要内容,如果未能解决你的问题,请参考以下文章