c++ - 奇怪的 C++ 链表错误

标签 c++ macos x86 segmentation-fault paging

我在不同版本的 GNU 的不同机器上测试了这个代码片段,只有一台带有 Clang 1001.0.46.3 的奇怪 Mac 报告段错误。这段代码是否有地址问题或指针问题?

#include <iostream>
#include <vector>

using namespace std;

class Node
{
public:
    Node* next;
    int val;

};

class List
{
private:
    Node* head;
    Node* tail;
public:
    List()
    {
        head = tail = nullptr;
    }
    bool isEmpty()
    {
        if(!head && !tail) return true;
        return false;
    }
    void pushBack(int num)
    {
        Node* newNode = new Node;
        newNode->val = num;
        if(isEmpty()) head = tail = newNode;
        else
        {
            tail->next = newNode;
            tail = tail->next; 
        }
    }

    void pushFront(int num)
    {
        Node* newNode = new Node;
        newNode->val = num;
        if(isEmpty()) head = tail = newNode;
        else
        {
            Node* tmp = head;
            newNode->next = tmp;
            head = newNode;
        }
    }

    void popBack()
    {
        if(head == tail) {delete head; head = nullptr; return;}
        Node* tmp = head;
        while(tmp->next != tail) tmp = tmp->next;
        tail = tmp;
        delete tmp->next;
        tmp->next = nullptr;
    }

    void popFront()
    {
        if(head == tail) {delete head; head = nullptr; return;}
        Node* tmp = head;
        tmp = tmp->next;
        delete head;
        head = nullptr;
        head = tmp;
    }

    int findLen()
    {
        if(isEmpty()) return 0;
        int len = 0 ;   
        Node* tmp = head;
        while(tmp)
        {
            len++;
            //if(tmp == tail) break;
            tmp = tmp->next;
        }
        return len;
    }

    void inserter(int position, int num)
    {
        if(position > findLen() || isEmpty()) return;
        int index = 0;
        Node* tmp = head;
        Node* newNode = new Node;
        newNode->val = num;
        if(position == 0) {pushFront(num); return;}
        else if(position == findLen()) {pushBack(num); return;}
        while(tmp->next)
        {
            index++;
            if(index == position)
            {
                Node* tmp2 = tmp->next;
                tmp->next = newNode;
                newNode->next = tmp2;
                return;
            }   
            tmp = tmp->next;
        }
    }

    void print()
    {
        if(isEmpty()) return;
        cout << "list = ";
        Node* tmp = head;

        while(tmp)
        {
            cout << tmp->val << " ";
            if(tmp == tail) break;
            tmp = tmp->next;
        }
        cout << endl;
    }
};



int main()
{   
    cout << "delete added" << endl;
    List testList;
    testList.pushBack(5);
    testList.pushBack(10);
    testList.pushBack(15);
    testList.pushBack(20);                          // after this line, we got segmentation fault
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    testList.pushFront(5);
    testList.pushFront(10);
    testList.pushFront(15);
    testList.pushFront(20);
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    testList.inserter(0,8);
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    testList.inserter(9,555);
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    testList.inserter(5,333);
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    cout << "popBack" << endl;
    testList.popBack();
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    cout << "popFront" << endl;
    testList.popFront();
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    cout << "popBack" << endl;
    testList.popBack();
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    cout << "popFront" << endl;
    testList.popFront();
    cout << "len = " << testList.findLen() << endl;
    testList.print();

    return 0;
}

跟进:嘿,伙计们,我刚刚自己得到了一些线索。我认为问题应该出在操作系统方面。检查相关的汇编代码后,我注意到即使局部变量的默认初始化值为 0,但它们并不总是零。我认为问题应该是操作系统的分页方案。我将尽力弄清楚 MacOS(内核 10.15.1)和 linux 如何选择页面以及如何为局部变量生成随机值。如果有人知道这个领域或有任何线索可以弄清楚,请随时告诉我。干杯。

最佳答案

您的问题是在每个 Node 中,next 成员未初始化。

取消注释行 //if(tmp == tail) 中断; 在方法 findLen 中也是一个解决方案。

解决此问题的正确方法是将您的 Node 类重写为

class Node
{
public:
    Node* next = nullptr;
    int val;

};

无论如何,我希望这只是家庭作业或练习,否则请使用旧的std::list

关于c++ - 奇怪的 C++ 链表错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58834292/

相关文章:

当程序从终端运行时,clock_gettime 需要更长的时间来执行

c++ - 为什么强制 constexpr 只有编译时错误?

c++ - 关于如何使用 cpp-netlib 进行异步 http get 请求的示例

c++ - 将 8 个 bool 值保存到 1 个字节中

linux - 当我在 shell 脚本中运行但在终端控制台中成功运行时抛出错误

linux -/usr/bin/ld : skipping incompatible foo. 所以在搜索 foo 时

c++ - 我错过了什么纹理无法正常工作 OpenGL

eclipse - 从 Eclipse 中删除 "Build Workspace"键盘快捷键

Python 2.7.9 Mac OS 10.10.3 消息 "setCanCycle: is deprecated. Please use setCollectionBehavior instead"

multithreading - TLS 可变查找速度