堆栈析构函数中的双重释放或损坏

发布于 2024-12-29 15:43:07 字数 1873 浏览 0 评论 0原文

我很确定问题出在 while (!empty()) pop(); 因为在我将其注释掉之后。一切正常。但它不会删除 head。这部分有什么问题吗?

其意图如下:LinkedList有两个数据成员,headtail。当列表为空时,它们都应该等于0。当列表非空时,headtail 都应非零,并且它们应分别引用列表中的第一项和最后一项。并且应该有一条通过 next_ 指针从 headtail 的路径。如果列表只有一项,则 head == tail

#include <iostream>
//stack using linked list
class LinkedList {
 public:
  LinkedList() : head(0), tail(0) {}
  ~LinkedList() {
    while (!empty()) pop();
    std::cout<< "~LinkedList" << std::endl;
  }
  void pop() {
    node* temp;
    temp = head;
    for ( ; temp->next_ != 0; temp = temp->next_) {
      tail = temp;
    } 
    delete temp; 
    tail->next_ = 0;
    std::cout << "pop()" << std::endl;
  } //removes, but does not return, the top element
  int top() {
    return tail->value_;
  } //returns, but does not remove, the top element
  bool empty() {
    return head == 0;
  }
  void push(const int& value) {
    node* element = new node(value);
    if (empty()) {
      head = tail = element;
    } else {
      tail->next_ = element;
      tail = element;
    }
  } //place a new top element
 private:
  class node {
   public:
    node(const int& input) : value_(input), next_(0) {};
    int value_; //store value
    node* next_; //link to the next element
  };
  node* head;
  node* tail;
};
int main() {
  LinkedList list;
  list.push(1);
  list.push(2);
  std::cout << list.top() << std::endl;
  list.pop();
  std::cout << list.top() << std::endl;
  return 0;
}

通过将析构函数更改为以下代码解决了该问题:

  ~LinkedList() {
    while (head != tail) pop();
    delete head;
    std::cout<< "~LinkedList" << std::endl;
  }

I am pretty sure the problem is at while (!empty()) pop(); because after I commented it out. everything works fine. but it doesn't delete head. what's wrong with this part?

The intention is as follows: LinkedList has two data members, head and tail. When the list is empty, these should both be equal to 0. When the list is non-empty, then both head and tail shall be non-zero, and they should refer to the first and last items in the list respectively. And there shall be a path from head to tail via the next_ pointers. If the list has only one item, then head == tail.

#include <iostream>
//stack using linked list
class LinkedList {
 public:
  LinkedList() : head(0), tail(0) {}
  ~LinkedList() {
    while (!empty()) pop();
    std::cout<< "~LinkedList" << std::endl;
  }
  void pop() {
    node* temp;
    temp = head;
    for ( ; temp->next_ != 0; temp = temp->next_) {
      tail = temp;
    } 
    delete temp; 
    tail->next_ = 0;
    std::cout << "pop()" << std::endl;
  } //removes, but does not return, the top element
  int top() {
    return tail->value_;
  } //returns, but does not remove, the top element
  bool empty() {
    return head == 0;
  }
  void push(const int& value) {
    node* element = new node(value);
    if (empty()) {
      head = tail = element;
    } else {
      tail->next_ = element;
      tail = element;
    }
  } //place a new top element
 private:
  class node {
   public:
    node(const int& input) : value_(input), next_(0) {};
    int value_; //store value
    node* next_; //link to the next element
  };
  node* head;
  node* tail;
};
int main() {
  LinkedList list;
  list.push(1);
  list.push(2);
  std::cout << list.top() << std::endl;
  list.pop();
  std::cout << list.top() << std::endl;
  return 0;
}

fixed the problem by changing the destructor to the following codes:

  ~LinkedList() {
    while (head != tail) pop();
    delete head;
    std::cout<< "~LinkedList" << std::endl;
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清晨说晚安 2025-01-05 15:43:07

您的问题的一部分在这里

bool empty() {
    return head == 0;
}

head何时设置为0NULL)?绝不?

You have one part of your problem here

bool empty() {
    return head == 0;
}

When is head set to 0 (NULL)? Never?

痴情 2025-01-05 15:43:07

pop() 是错误的。当只剩下一个元素时,headtail 都指向它。因此,当您删除 temp 时,您实际上同时删除了 headtail,那么您就是:

  • 访问 tail< /code>,它现在是一个已释放的指针,并且

  • 不设置 tailhead 回到 0

pop() is wrong. When you have only one element left, both head and tail point to it. So when you delete temp, you are in fact deleting both head and tail, then you are:

  • accessing tail, which is now a deallocated pointer, and

  • not setting tail or head back to 0

诗化ㄋ丶相逢 2025-01-05 15:43:07

如果您 pop() 列表中的最后一个元素,您的 pop() 不会修复 this->head

Your pop() doesn't fix this->head if you pop() the last element in the list.

爱的故事 2025-01-05 15:43:07

您可以在开始时添加这些检查。这是一个无聊的解决方案,也许您应该更改整体设计,但此代码应该纠正您当前的 pop 算法。特别是,当弹出最后一项时,head 和 tail 都应该设置为零。

另外,它应该是 delete tail->next_;,而不是 delete temp;,就在 tail->next_ = 0; 之前

  void pop() {
    if(head == 0) {
        // the list is empty, there's nothing to pop. This should be an error!
    }
    if((head != 0 && head == tail) {
        // there is only one item in the list
        delete head;
        head = 0;
        tail = 0;
    }
    node* temp;
    temp = head;
    for ( ; temp->next_ != 0; temp = temp->next_) {
      tail = temp;
    } 
    delete tail->next_; 
    tail->next_ = 0;
    std::cout << "pop()" << std::endl;
  }

我还没有测试过这个,但它应该可以解决一些问题。

You could add these checks at the start. This is a boring solution, and perhaps you should change your overall design, but this code should correct your current algorithm for pop. In particular, when popping the last item, both head and tail should be set to zero.

Also, it should be delete tail->next_;, not delete temp;, just before the tail->next_ = 0;

  void pop() {
    if(head == 0) {
        // the list is empty, there's nothing to pop. This should be an error!
    }
    if((head != 0 && head == tail) {
        // there is only one item in the list
        delete head;
        head = 0;
        tail = 0;
    }
    node* temp;
    temp = head;
    for ( ; temp->next_ != 0; temp = temp->next_) {
      tail = temp;
    } 
    delete tail->next_; 
    tail->next_ = 0;
    std::cout << "pop()" << std::endl;
  }

I haven't tested this, but it should fix some of the problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文