首页 > 解决方案 > 如何让我的队列在 C++ 中工作?未处理的异常:访问冲突读取位置

问题描述

我在 C++ 中实现队列时遇到了问题。我寻找了类似的问题,但没有发现任何有用的东西。

我正在使用 Visual Studio 2019。

我在 Main.cpp、Queue.h 和 Queue.cpp、Patient.h 和 Patient.cpp 中分离了我的程序。我试图将这个概念从 Java 转换为 C++,但我找不到我的函数 getInfo() 的解决方案。

我收到这样的异常:Queue.exe 中 0x7C0EF3BE (ucrtbased.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0xE8884D8D。

如果有人可以帮助我解决我的问题并解释我做错了什么,那就太好了。我只是一个初学者,所以请不要对我太苛刻xD

主要.cpp:

#include "Queue.h"
#include "Patient.h"

int main() {
    Queue queue;
    Patient patient1("Name1");
    Patient patient2("Name2");
    queue.add(patient1);
    queue.add(patient2);
    queue.getInfo();
}

队列.h:

#pragma once

#include <iostream>
#include "Patient.h"

using namespace std;

class Queue {

private:
    Patient* beginning;
    Patient* end;
    int amount;

public:
    Queue();
    void add(Patient p);
    Patient remove();
    void getInfo();
};

队列.cpp:

#include "Queue.h"

Queue::Queue() {
    beginning = 0;
    end = 0;
    amount = 0;
}

void Queue::add(Patient p) {
    if (amount == 0) {
        beginning = &p;
        end = &p;
    } else {
        end->setFollower(p);
        end = &p;
    }
    amount++;
}

Patient Queue::remove() {
    if (amount == 0) {
        cout << "You can't remove a patient. The Queue is empty!" << endl;
    } else {
        *beginning = beginning->getFollower();
        amount--;
    }
    return *beginning;
}

void Queue::getInfo() {
    if (amount == 0) {
        cout << "The Queue is empty!" << endl;
    } else {
        cout << "There are " << amount << " Patients in the Queue!" << endl;
        cout << "The following list provides all Patients in the Queue-order:" << endl;
        beginning->getInfo();
    }
}

患者.h:

#pragma once

#include <iostream>
#include <string>

using namespace std;

class Patient {

private:
    string name;
    Patient* follower;
    string* nameptr;

public:
    Patient(string newname);
    void setFollower(Patient p);
    Patient getFollower();
    void getInfo();
};

患者.cpp:

#include "Patient.h"

    Patient::Patient(string newname) {
        name = newname;
        follower = 0;
        nameptr = &name;
    }

    void Patient::setFollower(Patient p) {
        follower = &p;
    }

    Patient Patient::getFollower() {
        return *follower;
    }

    void Patient::getInfo() {
        cout << *nameptr << endl;
        if (follower == 0) {
            cout << "No follower existing!" << endl;
        }
        else {
            follower->getInfo();
        }
        cin.get();
    }

标签: exceptionvisual-c++

解决方案


在某些地方,您会将按值传递与按引用传递混为一谈。

首先,第一个问题在这里:

void Queue::add(Patient p) {
    if (amount == 0) {
        beginning = &p;
        end = &p;
    } else {
        end->setFollower(p);
        end = &p;
    }
    amount++;
}

您传递的是 Patient p 的值,而不是对实际对象的引用。要解决此问题,您只需在函数调用中添加一个“&”,如下所示:

void Queue::add(Patient& p) {
    if (amount == 0) {
        beginning = &p;
        end = &p;
    } else {
        end->setFollower(p);
        end = &p;
    }
    amount++;
}

注意参数列表中的“&”。然后你还必须更新函数头:

class Queue {

private:
    Patient* beginning;
    Patient* end;
    int amount;

public:
    Queue();
    void add(Patient& p);
    Patient remove();
    void getInfo();
};

您还必须通过引用传递您的 setFollower 函数:

void Patient::setFollower(Patient& p) {
    follower = &p;
}

并在头文件中:

void setFollower(Patient& p);

您需要知道的是,在 C++ 中,所有参数都是按值传递的,除非您在函数的参数列表中指定按引用传递。如果您想了解更多信息,这里有一篇关于将变量传递给函数的文章 ( https://iq.opengenus.org/call-by-value-vs-call-by-reference-cpp/ )。


推荐阅读