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

Calling delete[] inside destructor in c++

提问人:Aagman 提问时间:12/20/2017 最后编辑:Nasser Al-ShawwaAagman 更新时间:12/23/2017 访问量:550

问:

我对下面的代码有疑问,析构函数内部有一个析构函数,我只是想知道此删除是否有任何堆栈过流,这可能是递归调用析构函数的结果。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;
  }

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

请解释

C++ 管理 内存泄漏 析构函数 赋值运算符

评论

0赞 Steve 12/20/2017
line是指向 的指针,它没有析构函数。调用它将释放您分配的内存,仅此而已。chardelete
0赞 Martin Bonner supports Monica 12/20/2017
正如答案所说,没有递归。但是,如果有人这样做,您的副本分配代码就会有问题。这是自我分配,而且大错特错。最好的解决方案是 1.编写一个合适的复制构造函数。2. 为 Line 编写 std::swap 的专用化。3. 复制分配按进行,并且只是做 .如果你的交换是无抛出的(应该是),那么这提供了强大的异常保证。Line l("Hello World); Line *p = &l; l = *p;otherstd::swap(*this, other); return *this;

答:

1赞 Bathsheba 12/20/2017 #1

delete[] line;将构造函数和赋值运算符中的语句配对。请注意,如果设置为 ,则为无操作,这是分支赋值的作用,尽管它草率地使用了 代替 。new char[strlen(s)+1];delete[] line;linenullptrelse0nullptr

请放心,析构函数不是递归调用的。只是析构函数用于释放任何分配的内存。

但是使用作为类成员变量,甚至整个类本身会容易得多。您的代码中存在一些微妙的错误 - 自我赋值就是其中之一,并且缺少复制构造函数。让 C++ 标准库为您处理所有这些。简而言之,你可以写std::string line;

int main() {
    std::string array[] = {"abc", "def", "xyz"};
    std::string tmp;
}
1赞 463035818_is_not_an_ai 12/20/2017 #2

参数是 ,即没有调用析构函数(也没有递归调用析构函数)。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

评论

2赞 Peter 12/20/2017
delete this如果对象不是使用新表达式创建的,则会导致未定义的行为。
2赞 Erik 12/20/2017 #3

不,它不会。

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

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

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

1赞 Rishikesh Chandra 12/23/2017 #4

默认情况下,C++ 负责 char* 的 delete[],因此您不需要执行任何操作。