【问题标题】:How to delete this in C++ class (so that it doesn't enter infinte loop)如何在 C++ 类中删除它(使其不会进入无限循环)
【发布时间】:2021-08-31 12:29:01
【问题描述】:
  • 我没有很好地实现一个双向链表,我遇到了一个 内存泄漏问题。
  • 我需要删除的最大问题是 我在堆中动态分配内存的节点。
  • 当 double_linked_list 类的删除函数为 调用。
  • 我尝试调试,但没有成功。
class double_node{
public:
    // Data members
    ll data;
    double_node * next;
    double_node * prev;

    // Functions
    double_node(){
        this->next = nullptr;
        this->prev = nullptr;
        this->data = LLONG_MIN;
    }

    double_node(ll data, double_node * next, double_node * prev){
        this->data = data;
        this->next = next;
        this->prev = prev;
    }

    // WARNING : Memory Leak
    // I don't know why defining a destructor gives an error
     ~double_node(){
         cerr << "~double_node() is called\n";
          if(this != nullptr){
              delete this;
          }
     }
};

class double_linked_list{
public:
    double_node * head = new double_node;
    double_node * tail = new double_node;

    double_linked_list(){
        // Head part
        head->data = LLONG_MIN;
        head->next = tail;
        head->prev = nullptr;
        // Tail part
        tail->data = LLONG_MIN;
        tail->next = nullptr;
        tail->prev = head;
        
    }
    void append(ll data){
        if(head->data == LLONG_MIN){
            head->data = data;
        }
        else if(tail->data == LLONG_MIN){
            tail->data = data;
        }
        else{
            double_node * temp = tail;
            double_node * last = new double_node;
            
            // Setting up last
            last->data = data;

            temp->next = last;
            last->prev = temp;
            last->next = nullptr;

            tail = last;
        }
        
    }

    void remove(ll data){
        double_node * temp = head;
        while(temp != nullptr and temp->data != data){
            temp = temp->next;
        }
        if(temp->data == data){
            double_node * y = temp->prev;
            double_node * x = temp;
            double_node * z = temp->next;
            if (z != nullptr){
                z->prev = y;
            }
            if(y != nullptr){
                y->next = z;
            }
            if(x == head){
                head = z;
            }
            if(temp != nullptr){
                x->next = nullptr;
                x->prev = nullptr;
                delete x;
            }

        }
    }
};

【问题讨论】:

  • ll data; -- 什么是ll?不要从竞争性编码网站复制不良的编码习惯。您要使用的类型是int64_t,而不是ll。然后this-&gt;data = LLONG_MIN; --> data = std::numeric_limits&lt;int64_t&gt;::min();
  • 不要delete this;在析构函数中。在析构函数中,对象已经被销毁了。
  • 调试是一项帮助验证和改进代码的关键技能。设置断点,单步执行代码,然后观察会发生什么。
  • 最好是了解更多关于所有权和重新实现链表的信息。您应该从所有者那里删除数据,因此不要在数据中使用 delete this(在析构函数中)。
  • if(this != nullptr){ -- 这个权利有一个错误。编译器可以完全消除这段代码,因为this 永远不会是nullptr

标签: c++ linked-list c++17 doubly-linked-list


【解决方案1】:

如何在 C++ 类中删除这个(使其不进入无限循环)

不删除this。永远不要在析构函数中这样做。而且几乎没有理由在任何函数中这样做。

只需完全删除~double_node。该节点不拥有任何资源,因此不需要用户定义的析构函数。

我遇到了内存泄漏问题。

您需要定义 ~double_linked_list 循环遍历节点并删除它们。您还需要关注the rule of 5

【讨论】:

    【解决方案2】:

    你的delete this在这里递归调用自己。

     ~double_node(){
         cerr << "~double_node() is called\n";
          if(this != nullptr){
              delete this;
          }
     }
    

    你可以删除这个析构函数。

    http://www.cplusplus.com/reference/new/operator%20delete/中所述

    带有删除操作符的表达式,首先调用相应的 析构函数(用于类类型),然后调用释放函数。

    在某些情况下您可以使用delete this,但您应该知道自己在做什么。以下是一些关于此的提示: https://isocpp.org/wiki/faq/freestore-mgmt#delete-this

    此外,您应该在 remove 函数中退出 while 循环后检查 temp 是否为空。否则在尝试删除它找不到的东西时会出现段错误。

    【讨论】:

    • 谢谢!修正了错字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多