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

时间:2012-01-28 15:40:24

标签: c++ g++

我很确定问题发生在while (!empty()) pop();,因为在我评论之后。一切正常。但它没有delete head。这部分出了什么问题?

目的如下:LinkedList有两个数据成员headtail。当列表为空时,这些应该都等于0。当列表非空时,headtail都应为非零,并且它们应分别引用列表中的第一个和最后一个项。并且应该有headtail之间通过next_指针的路径。如果列表只有一个项目,那么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;
  }

4 个答案:

答案 0 :(得分:2)

你有一部分问题

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

head何时设置为0NULL)?从未?

答案 1 :(得分:1)

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

  • 访问tail,现在是一个解除分配的指针,

  • 未将tailhead设置为0

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

此外,它应该在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;
  }

我没有对此进行过测试,但它应该解决一些问题。