简体   繁体   English

删除功能C的读取访问冲突异常

[英]Read access violation exception for a delete function c++

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

class Person{
public:
    string name;
    int age, height, weight;

    Person(string name = "empty", int age = 0, int height = 0, int weight = 0) {
        this->name = name;
        this->age = age;
        this->height = height;
        this->weight = weight;
    }
    Person operator = (const Person &P) {
        name = P.name;
        age = P.age;
        height = P.height;
        weight = P.weight;

        return *this;
    }

    friend ostream& operator<<(ostream& os, const Person& p);
};

ostream& operator<<(ostream& os, Person& p) {
    os << "Name: " << p.name << "   " << "Age: " << p.age << "     " << "Height: " << p.height << " " << "Weight: " << p.weight << "\n";
    return os;
};

class Node {
public:
    Person* data;
    Node* next;
    Node(Person*A) {
        data = A;
        next = nullptr;
    }
};

class LinkedList {
public:
    Node * head;
    LinkedList() {
        head = nullptr;
    }

    void InsertAtHead(Person*A) {
        Node* node = new Node(A);
        node->next = head;
        head = node;
    }
    void InsertAtEnd(Person*A) {
        if (head == nullptr) {
            InsertAtHead(A);
        }
        else {
            Node* node = new Node(A);
            Node* temp = head;
            while (temp->next != nullptr) {
                temp = temp->next;
            }
            temp->next = node;
        }
    }
    void InsertAtPosition(Person*A, int pos) {
        if (head == nullptr) {
            InsertAtHead(A);
        }
        else {
            Node* node = new Node(A);
            Node* temp = head;
            for (int i = 1; i < pos - 1; i++) { temp = temp->next; }
            node->next = temp->next;
            temp->next = node;
        }
    }
    void DeleteByValue(string search_name) {
        Node* temp = head;
        while (temp != nullptr) {
            if (temp->data->name == search_name) {
                delete(temp);
            }
            else {
                temp = temp->next;
            }
        }
        cout << "No person with that name was in the list" << endl;
    }

    void DeleteFromHead() {
        if (head != nullptr) {
            Node* temp = head;
            head = head->next;
            delete temp;
        }
    }
    void DeleteFromEnd() {
        Node* prev = nullptr;
        Node* temp = head;
        if (head == nullptr) { cout << "Nothing to delete" << endl; }
        else if (head->next == nullptr) { DeleteFromHead(); }
       else {
            while (temp->next != nullptr) {
                prev = temp;
                temp = temp->next;
            }
            prev->next = nullptr;
            delete temp;
        }
    }
    void DeleteAtPosition(int pos) {
        Node* prev = nullptr;
        Node* temp = head;
        if (head == nullptr) { cout << "Nothing to delete" << endl; }
        else if (pos == 1) { DeleteFromHead(); }
        else {
            for (int i = 1; i < pos; i++) {
                prev = temp;
                temp = temp->next;
            }
            prev->next = temp->next;
            delete temp;
        }
    }
    void UpdateAtPosition(Person*A, int pos) {
        if (head == nullptr) { cout << "No element in the list"; return; }
        if (pos == 1) { head->data = A; }
        else {
            Node* temp = head;
            for (int i = 1; i < pos; i++) {
                temp = temp->next;
            }
            temp->data = A;
        }
    }

    void Print() {
        Node* temp = head;
        while (temp != nullptr) {
            cout << *(temp->data);
            temp = temp->next;
        }
        cout << endl;
    }
};
int main() {
    LinkedList* list = new LinkedList();
    Stack* stack = new Stack(3);
    DynamicStack* dstack = new DynamicStack();


    cout << "Linked List" << endl;
    cout << "-----------" << endl;
    list->InsertAtHead(new Person("Jeremy", 22, 70, 145));                  list->Print();
    list->InsertAtHead(new Person("Samantha", 20, 63, 115));                list->Print();
    list->InsertAtEnd(new Person("Chris", 19, 70, 200));                    list->Print();
    list->DeleteByValue("Chris");                                           list->Print();
    list->InsertAtPosition(new Person("Grace", 15, 64, 150), 3);            list->Print();
    list->InsertAtPosition(new Person("Robert", 15, 67, 160), 4);           list->Print();
    list->DeleteFromHead();                                                 list->Print();
    list->DeleteFromEnd();                                                  list->Print();
    list->DeleteAtPosition(2);                                              list->Print();
    list->UpdateAtPosition(new Person("Jeremy", 23, 70, 155), 1);           list->Print();
    cout << endl;
    cout << endl;
    system("pause");
}

I am new to C++ and I am trying to create a function for my linked list class that will Delete a Person object by the Persons name. 我是C ++的新手,我试图为我的链表类创建一个函数,该函数将通过Persons名称删除Person对象。 I know this isn't showing the rest of the class, but I know it is all working and the error lies within this function. 我知道这没有显示该类的其余部分,但是我知道它都可以正常工作,并且该函数中存在错误。 When I try and run the program there is an exception being thrown saying "Read Access Violation" on the line "delete(temp);". 当我尝试运行该程序时,在“ delete(temp);”行上抛出一个异常,说“读取访问冲突”。 I am confident that I need to move the rest of the nodes back and make another node such as "prev" to store temp in before deleting it, but I have tried a lot and as I said I am new. 我有信心,我需要将其余节点移回去,并在删除临时节点之前先制作另一个节点(例如“ prev”)以存储临时文件,但是我已经做了很多尝试,并且正如我所说的,我是新手。 Can anyone tell me what I need to add to get this to work, and please explain why so I am learning from it. 谁能告诉我要使其正常工作需要添加什么,请解释原因,以便我从中学习。 Thanks in advance! 提前致谢!

After you find a match, you delete it and the loop keeps going since you never set temp to nullptr . 找到匹配项后,将其删除,并且循环将继续进行,因为您从未将temp设置为nullptr temp now is no longer valid since it has just been deleted, however, you try to access the data it points to on the next iteration, producing undefined behavior, then you delete it, likely causing the crash. temp现在不再有效,因为它刚刚被删除,但是,您尝试在下一次迭代中访问它指向的数据,产生未定义的行为,然后将其删除,可能导致崩溃。

To fix it, either break the loop after a match is found or keep track of the next node before you delete temp. 要解决此问题,请在找到匹配项后中断循环,或者在删除temp之前跟踪下一个节点。

Also, you should not have an output statement in the delete function since another person or you in the future won't expect a function that deletes elements to print stuff to the screen. 另外,在delete函数中不应包含输出语句,因为另一个人或您将来不会期望删除元素的函数将内容打印到屏幕上。

In your 在你的

void DeleteByValue(string search_name) {
    Node* temp = head;
    while (temp != nullptr) {
        if (temp->data->name == search_name) {
            delete(temp);
        }
        else {
            temp = temp->next;
        }
    }
    cout << "No person with that name was in the list" << endl;
}

once you find a match you just delete the memory but there is more to it, you need to handle both the previous node as well as head node if the name is found in the first node. 一旦找到匹配项,您只需删除内存,但还有更多内容,如果在第一个节点中找到了名称,则需要同时处理前一个节点和头节点。

something like this 像这样的东西

    Node* temp = head;
    Node* prev = nullptr;
    while (temp != nullptr) {
        if (temp->data->name == search_name) {
            if (prev != nullptr) {
              prev->next = temp->next;
            }
            else {
               head = temp->next;
            }
            delete temp;
            temp = nullptr;  
        }
        else {
            prev = temp;
            temp = temp->next;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM