c++ - operator= on pointers 可能导致 mac 上的段错误

标签 c++ macos terminal segmentation-fault operator-overloading

我正在尝试编写一个带有链表的类 Set 来存储整数。在我的 Mac 终端上编译和运行后,这是输出:

[]
[10]
[10, 20]
Segmentation fault: 11

但我期待看到以下输出:

[]
[10]
[10, 20]
[10, 20]
[10, 20, 30]

我想知道是我的 operator= 函数有问题,还是我不能将 operator= 函数与指针一起使用?如果是这样,我应该如何更正问题以使程序按预期输出?非常感谢您的帮助。提前致谢!

#include <iostream>
using namespace std;

class Node {
  public:
    int value;
    Node* next;
    Node(int n, Node* ptr = NULL) : value(n), next(ptr) {}
};

class Set {
  Node* head;
  friend ostream& operator<<(ostream&, const Set&);
  public:
    Set() : head(NULL) {}
    Set(const Set& another){ *this = another; }
    ~Set();
    Set& operator+=(const int&);
    Set& operator=(const Set&);
};

int main() {
    int num1 = 10;
    int num2 = 20;
    int num3 = 30;
    Set set1;
    cout << set1;
    Set* set2;
    set1 += num1;
    cout << set1;
    set1 += num2;
    cout << set1;
    set2 = new Set(set1);
    cout << *set2;
    *set2 += num3;
    cout << *set2;
    delete set2;
    return 0;
}

Set::~Set() {
    Node* current = head;
    while (current != NULL) {
        Node* temp = current;
        current = current->next;
        delete temp;
    }
}

Set& Set::operator+=(const int& aNum) {
    if (head == NULL) {
        head = new Node(aNum);
        return *this;
    }
    Node* previous = head;
    Node* current = head->next;
    while (current != NULL) {
        previous = current;
        current = current->next;
    }
    previous->next = new Node(aNum);
    return *this;
}

Set& Set::operator=(const Set& another) {
    if (this != &another) {
        Node* current = head;
        while (current != NULL) {
            Node* temp = current;
            current = current->next;
            delete temp;
        }
        Node* anotherCurrent = another.head;
        while (anotherCurrent != NULL) {
            *this += anotherCurrent->value;
            anotherCurrent = anotherCurrent->next;
        }
    }
    return *this;
}

ostream& operator<<(ostream& os, const Set& s) {
    os << "[";
    for (Node* p = s.head; p != NULL; p = p->next) {
        os << p->value;
        if (p->next != NULL)
            os << ", ";
    }
    os << "]" << endl;
    return os;
}

最佳答案

在复制之前删除以前的列表时,必须将 head 设置为 NULL,否则 += 运算符将使用 head 并且它当前未分配但不是 NULL

Set& Set::operator=(const Set& another) {
    if (this != &another) {
        Node* current = head;
        while (current != NULL) {
            Node* temp = current;
            current = current->next;
            delete temp;
        }
        head = NULL;   // <============== code to add
        Node* anotherCurrent = another.head;
        while (anotherCurrent != NULL) {
            *this += anotherCurrent->value;
            anotherCurrent = anotherCurrent->next;
        }
    }
    return *this;

顺便说一句,一个非常有趣的设计模式,必读:copy-and-swap idiom

关于c++ - operator= on pointers 可能导致 mac 上的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40427912/

相关文章:

c++ - 将字符串的每个单词插入 vector 并计算每个单词的出现

linux - 如何重新映射 Control+Space 以返回?

terminal - 如何自动转义粘贴到终端的字符串中的特殊字符?

terminal - iterm2 图像未内联显示

c++ - 使用指针修改动态字符数组

c++ - 嵌套类和 ADL

swift :NSBezier

python - 在 os x Lion 上运行 python 程序

c++ - 在编译时使用未知类型的对象类

node.js - nmap:ping 回显到 stderr