簡體   English   中英

C ++:嘗試將新節點添加到鏈接列表會產生“線程1:EXC_BAD_ACCESS(代碼= 1,地址= 0x0)”錯誤

[英]C++: Attempting to add new node to linked list yields “Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)” error

我正在編寫一個用於作業的程序,該程序可以創建和操作鏈表。 我在Node.cpp的Node :: SetData函數以及List.cpp的List :: Add_End行(特別是“ current-> SetData(data);”)中遇到一行“ EXC_BAD_ACCESS”錯誤,並且由於某種原因,main.cpp中的行(特別是“ // Add_End節點到列表”)。 我假設一旦修復了Node :: SetData錯誤,這些其他錯誤將自行解決。

在搜索Stack Overflow和Google之后,我無法確定為什么會發生此錯誤。 我認為這個問題( C ++的新功能,我不理解的“ EXC_BAD_ACCESS”錯誤 )會有所幫助,但是我仍然遇到問題。

我犯了什么編碼錯誤?

main.cpp

#include <iostream>
#include <cstddef>
using namespace std;

#include "List.h"

int main()
{
    // New list
    List list;
    Node *answer;

    // Add_End nodes to the list
    list.Add_End(111);
    list.Print();
    list.Add_End(222);
    list.Print();
    list.Add_End(333);
    list.Print();
    list.Add_End(444);
    list.Print();
    list.Add_End(555);
    list.Print();

    // Delete nodes from the list
    list.Delete(444);
    list.Print();
    list.Delete(333);
    list.Print();
    list.Delete(222);
    list.Print();
    list.Delete(555);
    list.Print();
    list.Delete(111);
    list.Print();

    cout << "Testing Add_Front: and others" << endl;
    list.Add_Front(888);
    list.Print();
    list.Add_Front(999);
    list.Print();
    list.Add_Front(49);
    list.Print();

    cout << "Checking find function" << endl;
    answer = list.Find(888);
    cout << "Value for node returned by find function call with 888 is " << answer->Data() << "." << endl;
    cout << "Checking find function" << endl;
    answer = list.Find(999);
    cout << "Value for node returned by find function call with 888 is " << answer->Data() << "." << endl;
    cout << "Checking find function" << endl;
    answer = list.Find(49);
    cout << "Value for node returned by find function call with 888 is " << answer->Data() << "." << endl;
    cout << "Call find function with value not in list." << endl;
    answer = list.Find(7);
    if (answer == NULL)
    {
        cout << "returned null pointer since 7 not found" << endl;
    }
    else
    {
        cout << "in else of answer == NULL where Value for node returned by find function call with 7 is " << answer->Data() << "." << endl;
    }

    cout << "testing delete_front: " << endl;
    list.Delete_Front();
    list.Print();
    cout << "testing delete_end: " << endl;

    list.Delete_End();
    list.Print();

    return 0;
}

清單.h

#ifndef LIST_H
#define LIST_H

#include <cstddef>

#include "Node.h"

class List
{
private:
    Node* head;

public:
    List();
    void Add_End(int data);
    void Delete(int data);
    void Delete_Front();
    void Add_Front(int data);
    void Delete_End();
    Node* Find(int data);
    void Print();    
};

#endif

List.cpp

#include <iostream>
#include <cstddef>
using namespace std;

#include "List.h"

List::List()
{
    head = NULL;
    return;
}

void List::Add_End(int data)
{
    Node* current;
    Node* newEnd = new Node();

    for (current = head; current != NULL; current = current->Next())
    {}
    current->SetData(data);
    current->SetNext(newEnd);
    newEnd->SetData(NULL);
    newEnd->SetNext(NULL);

    return;
}

void List::Delete(int data) {
    /*
     FILL IN CODE (will do later)
     */


    return;
}

void List::Delete_Front()
{
    /*
     FILL IN CODE (will do later)
     */

    return;
}

void List::Add_Front(int data)
{
    Node* newNode = new Node();
    newNode->SetData(data);
    newNode->SetNext(head);
    head = newNode;
    return;
}

void List::Delete_End()
{
    if (head == NULL)
    {
        cout << "List has no member so cannot delete end" << endl;
        return;
    }

    // check if one in length
    if (head->Next() == NULL)
    {
        head = NULL;
        return;
    }
    // 2 or greater in length

    Node* current;
    Node* prev;
    prev = head;
    for (current = head->Next(); current->Next() != NULL; current = current->Next())
    {
        prev = current;
    }
    prev->SetNext(NULL);
    return;
}

Node* List::Find(int data)
{
    Node* current;

    for (current = head; current != NULL && current->Data() != data; current = current->Next())
    {}
    if(current == NULL)
    {
        cout << "Did not find " << data << "." << endl;
        return NULL;
    }
    else // found
    {
        cout << "Found " << data << "." << endl;
        return current;
    }
}

void List::Print()
{
    Node* current;
    for (current = head; current != NULL; current = current->Next())
    {
        cout << current->Data() << " ";
    }
    cout << endl;

    return;
}

節點

#ifndef NODE_H
#define NODE_H

class Node
{
private:
    int data;
    Node* next;

public:
    Node();
    void SetData(int aData);
    void SetNext(Node* aNext);
    int Data();
    Node* Next();
};

#endif

Node.cpp

#include <cstddef>

#include "Node.h"

Node::Node()
{
    this->SetData(NULL);
    this->SetNext(NULL);
    return;
}

void Node::SetData(int aData)
{
    this->data = aData;
    return;
}

void Node::SetNext(Node* aNext)
{
    this->next = aNext;
    return;
}

int Node::Data()
{
    return data;
}

Node* Node::Next()
{
    return next;
}

第一次調用current-> SetData時(請參見下文),current為NULL,因此在訪問它時會出現頁面錯誤(頁面錯誤是現代操作系統在嘗試訪問未分配的內存時給您的錯誤。訪問沖突。)

void List::Add_End(int data)
{
    Node* current;
    Node* newEnd = new Node();

    for (current = head; current != NULL; current = current->Next())
    {}
    current->SetData(data);
    current->SetNext(newEnd);
    newEnd->SetData(NULL);
    newEnd->SetNext(NULL);

    return;
}

我設法更正了代碼,因此在其他人遇到相同問題的情況下,我將做些解釋。

變更在我解釋此修復程序之前,讓我解釋一下我所做的更改。 鏈表的最后一個節點本身可以​​保存數據值,而不僅僅是NULL (即,最后一個節點的data不必為NULL ,而其next應該為NULL ),所以我認為這樣會更好。 該代碼在涉及的每個位置都反映了這一點,例如List::Add_End(int data)函數。


解決方法:我修改了List構造函數以為列表創建頭節點。 因此,即使列表為空,鏈接列表也將始終至少具有一個節點。 稍后,我將說明程序如何識別空列表和非空列表。

這是原始的構造函數:

    List::List()
    {
        head = NULL;
        return;
    }

這是新的構造函數:

    List::List()
    {
        Node* headNode = new Node();
        head = headNode;

        return;
    }

為什么要進行此修改? 據我所知,我遇到了EXC_BAD_ACCESS錯誤,因為List::Add_End(int data)函數試圖操縱鏈接列表的head ,就好像它是節點對象一樣,而實際上並非如此。 (我相信這是他回答這個問題的意思。)這就是為什么我更改了編碼,使得即使列表為空,列表也始終包含頭節點。

區分空列表和非空列表。 我更改了Node構造函數以將data設置為整數-1122334455 ,而不是像我最初那樣將其設置為NULL 因此,如果列表為空,則head->Data() (即頭節點的data )為-112233455head->Next() (即頭節點的next )為NULL 這種方法的缺點是不可能有一個包含整數 -1122334455 的單項列表 ,但是我認為這個數字很可能是不必要的。 只要列表中至少包含兩項, head->Data()可以為-1122334455


新代碼:其余代碼反映了這些修改。 由於我僅對List.cpp和Node.cpp進行了重大更改,因此下面僅復制了它們。 其他三個程序文件基本上未更改。 僅供參考,有很多多余的returnthis是我不想刪除的。

List.cpp

    #include <iostream>
    #include <cstddef>
    using namespace std;

    #include "List.h"

    // -1122334455 is an arbitrary integer that is likely to never be needed by the user

    List::List()
    {
        Node* headNode = new Node();
        head = headNode;

        return;
    }

    Node* List::Add_End(int data)
    {
        // if list is empty (i.e., list has only head node with data == -1122334455 & next == NULL)
        if (head->Data() == -1122334455 && head->Next() == NULL)
        {
            head->SetData(data);

            return head;
        }
        // if list is nonempty
        else
        {
            Node* current;
            Node* newEnd = new Node();

            for (current = head; current->Next() != NULL; current = current->Next())
            {}
            current->SetNext(newEnd);
            newEnd->SetData(data);
            newEnd->SetNext(NULL);

            return newEnd;
        }
    }

    void List::Delete(int data)
    {
        Node* prev;
        Node* current;

        // if list is empty
        if (head->Data() == -1122334455 && head->Next() == NULL)
        {
            cout << "Cannot delete this datum because list is empty." << endl;
            return;
        }

        // if list contains 1 element
        if (head->Data() == data && head->Next() == NULL)
        {
            head->SetData(-1122334455);
            return;
        }
        else if (head->Data() != data && head->Next() == NULL)
        {
            cout << "Datum not found in list." << endl;
            return;
        }

        // if list contains 2 or more elements
        prev = head;

        for (current = head->Next(); current->Data() != data && current->Next() != NULL; current = current->Next())
        {
            prev = prev->Next();
        }
        if (current->Data() == data && current->Next() != NULL)
        {
            prev->SetNext(current->Next());
            delete current;
            return;
        }
        else if (current->Data() == data && current->Next() == NULL)
        {
            prev->SetNext(NULL);
            delete current;
            return;
        }
        else
        {
            cout << "Datum not found in list." << endl;
            return;
        }
    }

    void List::Delete_Front()
    {
        Node* origHead = head;
        Node* newHead = head->Next();

        head = newHead;
        delete origHead;

        return;
    }

    void List::Add_Front(int data)
    {
        // if list is empty
        if (head->Data() == -1122334455 && head->Next() == NULL)
        {
            head->SetData(data);
            return;
        }

        // if list is nonempty
        Node* newNode = new Node();
        newNode->SetData(data);
        newNode->SetNext(head);
        head = newNode;
        return;
    }

    void List::Delete_End()
    {
        if (head->Data() == -1122334455 && head->Next() == NULL)
        {
            cout << "List has no member so cannot delete end" << endl;
            return;
        }

        // check if one in length
        else if (head->Data() != -1122334455 && head->Next() == NULL)
        {
            head->SetData(-1122334455);
            return;
        }

        // 2 or greater in length
        else
        {
            Node* current;
            Node* prev;
            prev = head;
            for (current = head->Next(); current->Next() != NULL; current = current->Next())
            {
                prev = current;
            }
            prev->SetNext(NULL);
            return;
        }
    }

    Node* List::Find(int data)
    {
        Node* current;

        for (current = head; current != NULL && current->Data() != data; current = current->Next())
        {}
        if (current == NULL)
        {
            cout << "Did not find " << data << "." << endl;
            return NULL;
        }
        else // found
        {
            cout << "Found " << data << "." << endl;
            return current;
        }
    }

    void List::Print()
    {
        if (head->Data() == -1122334455 && head->Next() == NULL)
        {
            cout << "List is empty." << endl;
            return;
        }

        Node* current;
        for (current = head; current != NULL; current = current->Next())
        {
            cout << current->Data() << " ";
        }
        cout << endl;

        return;
    }

Node.cpp

    #include <cstddef>

    #include "Node.h"

    Node::Node()
    {
        // -1122334455 is an arbitrary integer that is likely to never be needed by the user
        this->SetData(-1122334455);
        this->SetNext(NULL);
        return;
    }

    void Node::SetData(int aData)
    {
        this->data = aData;
        return;
    }

    void Node::SetNext(Node* aNext)
    {
        this->next = aNext;
        return;
    }

    int Node::Data()
    {
        return this->data;
    }

    Node* Node::Next()
    {
        return this->next;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM