简体   繁体   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

I'm writing a program for a homework assignment that creates and manipulates a linked list. 我正在编写一个用于作业的程序,该程序可以创建和操作链表。 I am encountering an "EXC_BAD_ACCESS" error with the Node::SetData function in Node.cpp, as well as with a line in List::Add_End in List.cpp (specifically "current->SetData(data);") and a line in main.cpp for some reason (specifically "// Add_End nodes to the list"). 我在Node.cpp的Node :: SetData函数以及List.cpp的List :: Add_End行(特别是“ current-> SetData(data);”)中遇到一行“ EXC_BAD_ACCESS”错误,并且由于某种原因,main.cpp中的行(特别是“ // Add_End节点到列表”)。 I assume that once the Node::SetData error is fixed, these other errors will resolve themselves. 我假设一旦修复了Node :: SetData错误,这些其他错误将自行解决。

After searching through Stack Overflow and Google, I cannot determine why this error is occurring. 在搜索Stack Overflow和Google之后,我无法确定为什么会发生此错误。 I thought this question ( New to C++, "EXC_BAD_ACCESS" error I don't understand ) would help, but I'm still having issues. 我认为这个问题( C ++的新功能,我不理解的“ EXC_BAD_ACCESS”错误 )会有所帮助,但是我仍然遇到问题。

What coding error(s) have I made? 我犯了什么编码错误?

main.cpp 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;
}

List.h 清单.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 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;
}

Node.h 节点

#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 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;
}

While calling current->SetData for the first time (see below) current is NULL and so you get page fault when accessing it (page fault is the error modern OSes give you if you try to access unallocated memory. Under wndows the term usually is Access violation.) 第一次调用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;
}

I managed to correct the code, so I'll explain what I did in case someone else encounters the same problem. 我设法更正了代码,因此在其他人遇到相同问题的情况下,我将做些解释。

ALTERATION: Before I explain the fix, let me explain a change I made. 变更在我解释此修复程序之前,让我解释一下我所做的更改。 The last node of the linked list can hold a data value itself, not just NULL (ie, the last node's data does not need to be NULL , but its next should be NULL ), so I thought this would be better. 链表的最后一个节点本身可以​​保存数据值,而不仅仅是NULL (即,最后一个节点的data不必为NULL ,而其next应该为NULL ),所以我认为这样会更好。 The code reflects this in every location where it matters, such as the List::Add_End(int data) function. 该代码在涉及的每个位置都反映了这一点,例如List::Add_End(int data)函数。


THE FIX: I modified the List constructor to create a head node for the list. 解决方法:我修改了List构造函数以为列表创建头节点。 So, the linked list will always have at least one node, even if the list is empty. 因此,即使列表为空,链接列表也将始终至少具有一个节点。 I will explain how the program discerns between empty and nonempty lists later. 稍后,我将说明程序如何识别空列表和非空列表。

Here is the original constructor: 这是原始的构造函数:

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

Here is the new constructor: 这是新的构造函数:

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

        return;
    }

Why make this modification? 为什么要进行此修改? As far as I can tell, I encountered the EXC_BAD_ACCESS error because the List::Add_End(int data) function tried to manipulate the linked list's head as if it were a node object, when actually it was not. 据我所知,我遇到了EXC_BAD_ACCESS错误,因为List::Add_End(int data)函数试图操纵链接列表的head ,就好像它是节点对象一样,而实际上并非如此。 (I believe this is what marom meant in his answer to this question.) This is why I altered the coding such that the list always contains a head node, even when the list is empty. (我相信这是他回答这个问题的意思。)这就是为什么我更改了编码,使得即使列表为空,列表也始终包含头节点。

Discerning between empty and nonempty lists. 区分空列表和非空列表。 I altered the Node constructor to set data to the integer -1122334455 , instead of NULL like I originally did. 我更改了Node构造函数以将data设置为整数-1122334455 ,而不是像我最初那样将其设置为NULL So, if the list is empty, then head->Data() (ie, the head node's data ) is -112233455 and head->Next() (ie, the head node's next ) is NULL . 因此,如果列表为空,则head->Data() (即头节点的data )为-112233455head->Next() (即头节点的next )为NULL The downside to this approach is that it's impossible to have a one-item list containing the integer -1122334455 , but I figure this number is likely to be unneeded. 这种方法的缺点是不可能有一个包含整数 -1122334455 的单项列表 ,但是我认为这个数字很可能是不必要的。 As long as the list has at least two items, head->Data() can be -1122334455 . 只要列表中至少包含两项, head->Data()可以为-1122334455


NEW CODE: The rest of the code reflects these modifications. 新代码:其余代码反映了这些修改。 Since I only made significant changes to List.cpp and Node.cpp, I have reproduced only them below. 由于我仅对List.cpp和Node.cpp进行了重大更改,因此下面仅复制了它们。 The other three program files are essentially unchanged. 其他三个程序文件基本上未更改。 FYI, there are many redundant return 's and this 's that I didn't bother to delete. 仅供参考,有很多多余的returnthis是我不想删除的。

List.cpp 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 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.

相关问题 C ++节点分配错误:线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0) - C++ node assign error: Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) 线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)错误 - Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) error C ++ EXC_BAD_ACCESS(代码= 1访问= 0x0) - C++ EXC_BAD_ACCESS (code=1 access=0x0) 代码错误:线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0) - code error : Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) Xcode:线程1:制作邻接表时,EXC_BAD_ACCESS(代码= 1,地址= 0x0) - Xcode: Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) when making adjacency list 线程 1:xcode 中的 EXC_BAD_ACCESS(代码 = 1,地址 = 0x0)错误 - Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) error in xcode 调用 glCreateShader 时出现运行时错误“线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x0)” - Getting runtime error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" whencalling glCreateShader 线程 1:使用 scanf 时出现 EXC_BAD_ACCESS (code=1, address=0x0) 错误 - Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) error while using scanf 线程1:EXC_BAD_ACCESS(code = 2,address = 0x8)错误c ++ - Thread 1: EXC_BAD_ACCESS ( code=2,address=0x8) Error c++ 线程1:生成EXC_BAD_ACCESS(代码= 1,地址= 0x0)问题 - Thread 1 : EXC_BAD_ACCESS (Code = 1, address = 0x0) issue is generated
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM