代码实际上对我来说运行良好,但我必须将其提交给某人,作为回报,我收到一个我无法察觉的错误。
以下错误是:
munmap_chunk():无效指针(核心已转储)
错误似乎发生在名为:
loadLuggage
的方法中。我还用 Valgrind 检查了代码,但没有检测到可能的泄漏。也许我编译不正确。
#include <iostream>
#include <string>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;
template<typename T>
int izbrisiVrsto(queue<T> &queue) {
int numberOfRemoved = 0;
while (!queue.empty()) {
queue.pop();
numberOfRemoved++;
}
return numberOfRemoved;
}
template<typename T>
int deleteStack(stack<T> &stack) {
int numberOfDeleted = 0;
while (!stack.empty()) {
stack.pop();
numberOfDeleted++;
}
return numberOfDeleted;
}
class Traveler {
private:
string name;
string surname;
int age;
string emso; //used as ID
public:
Traveler(const string &name, const string &surname, int age, const string &emso)
: name(name), surname(surname), age(age), emso(emso) {
}
~Traveler() {}
string getName() const {
return name;
}
void setName(const string &name) {
this->name = name;
}
string getSurname() const {
return surname;
}
void setSurname(const string &surname) {
this->surname = surname;
}
int getAge() const {
return age;
}
void setAge(int age) {
this->age = age;
}
string getEmso() const {
return emso;
}
void setEmso(const string &emso) {
this->emso = emso;
}
};
enum TravelClass {
ECONOMY,
BUSINESS
};
class Luggage {
private:
int luggageID;
public:
Luggage(int id) : luggageID(id) {}
~Luggage() {}
int getLuggageID() const {
return luggageID;
}
void setLuggageID(int id) {
this->luggageID = id;
}
};
class BoardingTicket {
private:
Traveler traveler;
TravelClass travelClass;
Luggage luggage;
public:
BoardingTicket(const Traveler &traveler, const TravelClass &pr, const Luggage &luggage)
: traveler(traveler), travelClass(pr), luggage(luggage) {
}
~BoardingTicket() {}
Traveler getTraveler() const {
return traveler;
}
void setTraveler(const Traveler &traveler) {
this->traveler = traveler;
}
TravelClass getTravelClass() const {
return travelClass;
}
void setTravelClass(TravelClass travelClass) {
this->travelClass = travelClass;
}
Luggage getLuggage() const {
return luggage;
}
void setLuggage(const Luggage &luggage) {
this->luggage = luggage;
}
};
class Plane {
private:
int id; //plane ID
public:
stack<stack<Luggage> > trunk; //stack of luggage on plane = all travelers luggage
private:
unsigned int maxNumberOfLuggage; //number of maxium luggage on the heap
public:
Plane(int id, unsigned int maxNumberOfLuggage) :
id(id),
maxNumberOfLuggage(maxNumberOfLuggage) {
}
~Plane() {}
//get/set metode
int getID() const {
return id;
}
void setID(int id) {
this->id = id;
}
unsigned int getMaxNumberOfLuggage() const {
return maxNumberOfLuggage;
}
void setMaxNumberOfLuggage(unsigned int maxNumberOfLuggage) {
this->maxNumberOfLuggage = maxNumberOfLuggage;
}
void loadLuggage(queue<Luggage> &luggages) {
//TODO: implementation
while (luggages.empty() == false) {
stack<Luggage> pallet; //certain number of luggage on pallet
for (int i = 0; i < this->maxNumberOfLuggage; i++) {
Luggage luggage = luggages.front();
pallet.push(luggage);
luggages.pop();
}
this->trunk.push(pallet); //loading in trunk
}
}
queue<Luggage> unloadLuggage() {
//TODO: implementation
queue<Luggage> unloadingLuggage;
while (trunk.empty() == false) {
stack<Luggage> pallet = trunk.top();
trunk.pop();
for (int i = 0; i < pallet.size(); i++) {
unloadingLuggage.push(pallet.top());
pallet.pop();
}
}
return unloadingLuggage; //HACK: dummy return
}
};
class Airline {
public:
queue<BoardingTicket> boardingPeople; //people waiting to board on a plane
queue<Luggage> unloadedLuggage;
Airline() {}
~Airline() {}
void split(queue<BoardingTicket> &travelers, queue<BoardingTicket> &businessTravelers,
queue<BoardingTicket> &economyTravelers) {
//TODO: implementation
while (travelers.empty() == false) {
BoardingTicket traveler = travelers.front(); //izbira prvega potnika
if (traveler.getTravelClass() == ECONOMY) {
economyTravelers.push(traveler);
} else if (traveler.getTravelClass() == BUSINESS) {
businessTravelers.push(traveler);
}
travelers.pop(); //traveler vkrcan
}
}
queue<BoardingTicket> merge(queue<BoardingTicket> &businessTravelers, queue<BoardingTicket> &economyTravelers) {
//TODO: implementation
queue<BoardingTicket> merged;
while (economyTravelers.empty() == false) {
BoardingTicket first = economyTravelers.front();
merged.push(first);
economyTravelers.pop();
}
while (businessTravelers.empty() == false) {
BoardingTicket first = businessTravelers.front();
merged.push(first);
businessTravelers.pop();
}
return merged; //HACK: dummy return
return queue<BoardingTicket>(); //HACK: dummy return
}
queue<BoardingTicket> edit(queue<BoardingTicket> &waitingQueue) {
queue<BoardingTicket> businessTravelers;
queue<BoardingTicket> economyTravelers;
split(waitingQueue, businessTravelers, economyTravelers);
return merge(businessTravelers, economyTravelers);
}
void opravilaPriLetu(queue<BoardingTicket> readyPassengers,
queue<Luggage> appliedLuggage,
Plane lt) {
if (boardingPeople.size() != 0)
izbrisiVrsto(boardingPeople);
if (unloadedLuggage.size() != 0)
izbrisiVrsto(unloadedLuggage);
boardingPeople = edit(readyPassengers);
lt.loadLuggage(appliedLuggage);
//flying to destination
unloadedLuggage = lt.unloadLuggage();
}
};
bool MergeExclusivelyInBusinessClass() {
queue<BoardingTicket> business;
int luggageID = 0;
Traveler pt1("Victor", "Candice", 25, "1111111111111");
TravelClass pr1 = BUSINESS;
Luggage k1(luggageID++);
BoardingTicket kzv1(pt1, pr1, k1);
business.push(kzv1);
Traveler pt2("Charles", "Sennet", 17, "1111111111112");
TravelClass pr2 = BUSINESS;
Luggage k2(luggageID++);
BoardingTicket kzv2(pt2, pr2, k2);
business.push(kzv2);
Traveler pt3("Marc", "Cooper", 18, "1111111111113");
TravelClass pr3 = BUSINESS;
Luggage k3(luggageID++);
BoardingTicket kzv3(pt3, pr3, k3);
business.push(kzv3);
Traveler pt4("Frank", "McLorre", 45, "1111111111114");
TravelClass pr4 = BUSINESS;
Luggage k4(luggageID++);
BoardingTicket kzv4(pt4, pr4, k4);
business.push(kzv4);
queue<BoardingTicket> economy;
queue<BoardingTicket> mergeExpected = business;
Airline ld;
queue<BoardingTicket> actuallyMerged = ld.merge(business, economy);
if (mergeExpected.size() != actuallyMerged.size()) {
cout << "Metoda merge() did not fulfill did not fullfill with correct number of passenger ("
<< (int) mergeExpected.size() << "), but with " << (int) actuallyMerged.size() << " travelers." << endl;
return false;
}
while (!mergeExpected.empty() && !actuallyMerged.empty()) {
BoardingTicket actual = actuallyMerged.front();
actuallyMerged.pop();
BoardingTicket expected = mergeExpected.front();
mergeExpected.pop();
Traveler expectedP = expected.getTraveler();
Traveler actualP = actual.getTraveler();
TravelClass expectedPR = expected.getTravelClass();
TravelClass actualyPR = actual.getTravelClass();
Luggage expectedK = expected.getLuggage();
Luggage actualyK = actual.getLuggage();
if (expectedP.getEmso() != actualP.getEmso() || expectedP.getAge() != actualP.getAge() ||
expectedP.getSurname() !=
actualP.getSurname() ||
expectedP.getName() !=
actualP.getName() || expectedPR != actualyPR ||
expectedK.getLuggageID() !=
actualyK.getLuggageID()) {
cout << "Metoda merge() did not fill up expected queue of merged travelers with travelers that were given."
<< endl;
return false;
}
}
return true;
}
int main(int argn, char **args) {
if (MergeExclusivelyInBusinessClass())
cout << "Method merge() is successful." << endl;
else
cout << "Method merge() failed." << endl;
return 0;
}
我很难理解错误,并且不太确定如何解决它。有什么想法吗?
编辑1
我被告知错误可能是由 for 循环本身引起的,因为队列/堆栈大小不断变化,因此建议使用 while 循环。
编辑2
我终于找到了问题到底出现在哪里:
如果没有有关该错误的任何进一步信息,则很可能在 loadLuggage 函数的 for 循环中发生无效指针错误。 for 循环的第一行访问行李队列的前面元素,而不检查队列是否为空。因此,如果变量“maxNumberOfLuggage”已设置为大于队列大小的值,您将收到无效指针错误。尝试将 for 循环修改为:
for (int i = 0; i < this->maxNumberOfLuggage; i++) {
Luggage luggage = luggages.front();
pallet.push(luggage);
luggages.pop();
if(luggages.empty()) break; //add this line of code
}
这可能会解决您的问题。
如果不是,请提供有关错误的更多信息。
我没有确切的答案,对不起 Stack,但我最近确实遇到了类似的问题,我们有一个 1 行函数,它采用 std::string & 作为唯一参数并返回 void。我们在函数中没有返回调用,并且不断从 std::string & 参数收到 munmap_chunk 无效指针错误。错误出现在参数销毁期间,我们认为这与没有 return 语句有关。我自己和我的同事都没有时间进一步调查,只是提出“回报”;函数末尾阻止了错误。很可能代码仍然存在错误,但这对您来说是遗留代码 - 也许尝试输入返回值;在您的函数结束时会对您有所帮助。
根据编译器 101,我的猜测是,尝试将参数从堆栈中弹出是在访问无效内存,而返回会执行一些清理操作。