在C 中调用delete []内部破坏者

Calling delete[] inside destructor in c++

本文关键字:内部 破坏者 delete 调用      更新时间:2023-10-16

我在以下代码中有疑问,击曲线内有一个destructor 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;
  }

超载分配运算符中的删除是在分配新内存之前清洁内存(我已经在某个地方读取了它,如果我错了,请纠正我),但是此删除是否会调用destructor?

请解释

no,它不会。

此删除语句将删除字符数组。线路的破坏对象仅在销毁线对象时才调用。但是,这里不是这样。

变量线和对象/类线是不同的。

线变量在行类中是一个成员变量。因此,这两个名称看起来相同,但完全不同。

delete[] line;对构造函数和分配运算符中的new char[strlen(s)+1];语句配对。请注意,如果将line设置为nullptr,则delete[] line;是一个NO-OP,这是else分支分配所做的,尽管它使用0代替nullptr

可以确保攻击依次不被递归地称为。只是使用破坏者来释放任何分配的内存。

但是,使用std::string line;作为类成员变量,,甚至整个类本身 都将变得更加容易。您的代码中有一些微妙的错误 - 自我分配是其中之一,而复制构造函数丢失了。让C 标准库为您服务。简而言之,您可以写

int main() {
    std::string array[] = {"abc", "def", "xyz"};
    std::string tmp;
}

delete[]的参数是 char*,即没有destructor称为destructor(也没有对破坏者的递归调用)。

如果您有这样的破坏者:

 ~Line() { delete this; }   // DONT DO THIS !!! (also for other reasons it is not OK at all)

这将试图递归地调用自己,但您的代码看起来不错。

在分配操作员

line = new char[other.len()+1];

将分配新内存,并将指针(指向此内存)分配给line。这将导致您不再有旧内存的处理方法,并且要避免泄漏,您需要在之前将其删除。

c 默认情况下,请注意delete [] char*,因此您无需做任何事情。