提问人:Aagman 提问时间:12/20/2017 最后编辑:Nasser Al-ShawwaAagman 更新时间:12/23/2017 访问量:550
在 c++ 中在析构函数中调用 delete[]
Calling delete[] inside destructor in c++
问:
我对下面的代码有疑问,析构函数内部有一个析构函数,我只是想知道此删除是否有任何堆栈过流,这可能是递归调用析构函数的结果。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[] line;
将构造函数和赋值运算符中的语句配对。请注意,如果设置为 ,则为无操作,这是分支赋值的作用,尽管它草率地使用了 代替 。new char[strlen(s)+1];
delete[] line;
line
nullptr
else
0
nullptr
请放心,析构函数不是递归调用的。只是析构函数用于释放任何分配的内存。
但是使用作为类成员变量,甚至整个类本身会容易得多。您的代码中存在一些微妙的错误 - 自我赋值就是其中之一,并且缺少复制构造函数。让 C++ 标准库为您处理所有这些。简而言之,你可以写std::string line;
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
评论
delete this
如果对象不是使用新表达式创建的,则会导致未定义的行为。
不,它不会。
此 delete 语句将删除 char 数组。仅当销毁 Line 对象时,才会调用 Line 的析构函数。然而,这里的情况并非如此。
变量 line 和对象/类 Line 是不同的东西。
line 变量是 Line 类中的成员变量。所以这两个名字看起来是一样的,但完全不同。
默认情况下,C++ 负责 char* 的 delete[],因此您不需要执行任何操作。
下一个:双链表三巨头
评论
line
是指向 的指针,它没有析构函数。调用它将释放您分配的内存,仅此而已。char
delete
Line l("Hello World); Line *p = &l; l = *p;
other
std::swap(*this, other); return *this;