链表的复制构造函数导致内存错误

Copy constructor for a linked list leads to a memory error

提问人:alekscooper 提问时间:3/12/2020 最后编辑:Jabberwockyalekscooper 更新时间:3/12/2020 访问量:159

问:

我正在编写我自己的链表类(出于教育目的),这里是:

我的代码

#include <iostream>

using namespace std;

#define PRINT(x) #x << " = " << x << " "

struct ListNode {
  int val;
  ListNode* next = nullptr;
  ListNode(int x) : val(x), next(nullptr) {}
};

class LinkedList {
private:
  ListNode* _head;
  unsigned long long int _size;
public:

  LinkedList() :_head(nullptr), _size(0) {}

  LinkedList(ListNode* _h) :_head(_h), _size(0) {
    ListNode* node = _head;
    while (node != nullptr) {
      _size++;
      node = node->next;
    }
  }

  // Copy constructor
  LinkedList(const LinkedList& obj) {
    ListNode* node = obj._head;
    while (node != nullptr) {
      this->add(node->val);
      node = node->next;
    }
  }

  ~LinkedList() {
    while (_head != nullptr) {
      remove();
    }
  }

  void add(const int& value) {
    ListNode* node = new ListNode(value);
    node->next = _head;
    _head = node;
    _size++;
  }

  int remove() {
    int v = _head->val;
    ListNode* node = _head;
    _head = _head->next;
    delete node;
    _size--;
    return v;
  }

  void print() {
    if (size() == 0) {
      cout << "List is empty" << endl;
      return;
    }
    ListNode* node = _head;
    while (node->next != nullptr) {
      cout << node->val << " -> ";
      node = node->next;
    }
    cout << node->val << endl;
  }

  unsigned long long int size() { return _size; }
  ListNode* head() { return _head; }
};

int main() {

  LinkedList L;
  L.add(4);
  L.add(3);
  L.add(2);
  L.add(1);
  L.print();

  LinkedList L2(L);

  return 0;
}

问题是,当我运行此代码时,我收到以下错误:我不明白为什么。我在复制构造函数之外的逻辑很简单:我遍历我正在复制的列表,即 ,并向列表添加一个新元素,这是我要复制到的列表。由于我的函数创建了一个新元素,好吧,我看不到我的两个列表在哪里共享一个元素,我试图在析构函数中删除两次。我做错了什么?error for object 0x7fff5b8beb80: pointer being freed was not allocatedobjthisadd()new

C++ 指针链接 列表 复制构造函数

评论

1赞 user253751 3/12/2020
代码对我来说看起来不错。是否可以使用调试器查看错误来自哪一行代码?(在 Linux 上,当您运行程序时,将其放在程序的前面,当它打印错误并暂停时,键入以查看调用堆栈)gdbbt
0赞 Sanjeev 3/12/2020
您的代码在 VS2017 中运行良好,没问题,我可以毫无问题地运行它。尝试清洁溶液并重建并检查。
0赞 Jabberwocky 3/12/2020
到目前为止,代码对我来说看起来不错,你确定你运行的代码是你编译的代码吗?否则,请使用调试器。如果您不知道如何使用它,那么是时候开始学习了。
0赞 alekscooper 3/12/2020
@user253751我在 Mac OS X 上使用 CLion。我问了一个也使用 CLion + Mac OS X 的朋友(不过她的操作系统版本较新),她说她遇到了同样的错误。
1赞 aschepler 3/12/2020
不是这个程序中的问题,但不要忘记三法则:给一个.然后,您可以选择按照五法则改进该类。LinkedListoperator=(const LinkedList&)

答:

6赞 Landstalker 3/12/2020 #1

你忘了初始化你的 in copy 构造函数:_head

// Copy constructor
LinkedList(const LinkedList &obj) {

    _head = NULL; // <- Add This

    ListNode *node = obj._head;
    while (node != nullptr) {
        this -> add(node -> val);
        node = node -> next;
    }
}

评论

3赞 Ted Lyngmo 3/12/2020
LinkedList(const LinkedList &obj) : _head(nullptr) { ...
0赞 Landstalker 3/12/2020
@TedLyngmo 我来自老派...... ^^
1赞 Landstalker 3/12/2020
@TedLyngmo 所以,我来自一个非常非常古老的学校!^^