在c ++中调用析构函数中的delete []

时间:2017-12-20 10:47:04

标签: c++ memory-management memory-leaks destructor assignment-operator

我对以下代码有疑问,析构函数中有一个析构函数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;
  }

重载赋值运算符中的删除是在分配新内存之前清理内存(我已经在某处读过它,如果我错了就纠正我),但是这个删除会调用析构函数吗?

请解释

4 个答案:

答案 0 :(得分:2)

不,它不会。

此删除语句将删除char数组。只有在销毁Line对象时才会调用Line的析构函数。然而,情况并非如此。

变量行和对象/类Line是不同的东西。

line变量是Line类中的成员变量。所以这两个名字看起来是一样的,但完全不同。

答案 1 :(得分:1)

delete[] line;new char[strlen(s)+1];语句与构造函数和赋值运算符配对。请注意,如果delete[] line;设置为line,则nullptr为无操作,这是else分支分配的作用,尽管它在0中使用了nullptr std::string line;的地方。

请确保析构函数不会递归调用。只是析构函数用于释放任何已分配的内存。

但是使用int main() { std::string array[] = {"abc", "def", "xyz"}; std::string tmp; } 作为类成员变量,或者甚至整个类本身将会更容易。您的代码中存在一些微妙的错误 - 自我分配是其中之一,并且缺少复制构造函数。让C ++标准库为您处理所有这些。总之,你可以写

lineDataSet.setDrawCubic(true);
lineDataSet.notifyDataSetChanged();

答案 2 :(得分:1)

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。这将导致您无法处理旧内存,并且为了避免泄漏,您需要先删除它。

答案 3 :(得分:1)

默认情况下,C ++负责char *的delete [],因此你不需要做任何事情。