exception - 如何让我的队列在 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();
}
解决方案
在某些地方,您会将按值传递与按引用传递混为一谈。
首先,第一个问题在这里:
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/ )。