在使用标准向量函数时抛出 'std::bad_alloc' 的实例后调用终止
Terminate called after throwing an instance of 'std::bad_alloc' while using standard vector functions
我正在做一项作业,要求我们为真人游戏模拟 'elimination voting' 程序。为此,我们使用一个 class (Vote
) 来记录要淘汰的玩家的名字,另一个 (Voting
) 不会在任何地方实例化,因为它的成员是静态的 (我们需要他们)。选票存储在 Voting class.
内部的向量中
问题是,即使我使用 push_back
函数将选票存储在向量中,在 运行 程序几次后,我得到一个 std::length_error
和 what(): basic_string::_M_create
。在我关闭它并重新运行后,我第一次收到如标题中的错误 (std::bad_alloc
)。
有什么想法吗?我怀疑它与 vector 没有正确释放内存有关,但我不确定。
我的代码(Voting.h):
#ifndef VOTING_H_INCLUDED
#define VOTING_H_INCLUDED
#include <vector>
#include <map>
#include "Vote.h" //ignore this one
#include "Team.h" //this one too
class Voting
{
public:
static vector <Vote> votes; //votes cast during voting procedure
static map <string, int> results; //voting results (key: name, value: number of votes)
static void votingProcess(Team &team); //the whole voting procedure
};
#endif // VOTING_H_INCLUDED
Voting.cpp:
#include <vector>
#include <map>
#include <cstdlib>
#include "Vote.h"
#include "Voting.h"
using namespace std;
vector <Vote> Voting::votes(1); //initialize the vector for the votes
void voteCast(Team &team);
void Voting::votingProcess(Team &team)
{
voteCast(team);
}
void voteCast(Team &team)
{
int playerNumber = team.getNumberOfPlayers(); //number of players right now still in the team
int votingPlayer = 0; //index of the currently voting player
int votedPlayerIndex = -1; //index of the player to be voted for elimination
int reasonIndex = -1; //index of the selected reason for voting
Vote draft; //temporary empty vote
srand(time(NULL)); // initialize the RNG
Voting::votes.clear(); //clear the vector of any past votes
string reasons[4] = {"Den ta pame kala metaxi mas", "Einai ikanoteros/i apo emena kai ton/ti theoro apeili", "Den exei na prosferei kati stin omada", "Prospathei sinexeia na sampotarei tis prospatheies mas"};
//some reasons for elimination (i've tried smaller strings and even chars and it didn't work, so don't bother)
do
{
if (team.getPlayers()[votingPlayer].getAge() != 0 && team.getPlayers()[votingPlayer].getVotes() > 0)
//if the player with index votingPlayer has not been eliminated and has still votes to cast
{
do
{
votedPlayerIndex = rand() % 11; //select a random player for elimination
reasonIndex = rand() % 5; //select a random reason for it
}
while ((team.getPlayers()[votedPlayerIndex].getAge() == 0) || (votedPlayerIndex == votingPlayer) || (team.getPlayers()[votedPlayerIndex].getImmunity() == true));
// selection continues if the selected player has already been eliminated,
//if the selected player is the same as the voting player or if the selected player has immunity from elimination
team.getPlayers()[votingPlayer].setVotes(team.getPlayers()[votingPlayer].getVotes() - 1); //reduce the player's available votes by 1
draft.setVotedPlayer(team.getPlayers()[votedPlayerIndex].getName()); //write the name of the player to be voted in an empty Vote object
draft.setReason(reasons[reasonIndex]); //and the reason too
Voting::votes.push_back(draft); //push the Vote obj. in the vector
}
else
{
votingPlayer++; //ignore and get to the next player
}
}
while (votingPlayer < playerNumber); //vote casting continues until every player has casted a vote
}
Vote.h:
#ifndef VOTE_H_INCLUDED
#define VOTE_H_INCLUDED
#include <string>
#include <iostream>
using namespace std;
class Vote
{
string voted; //name of the player to be eliminated
string reason; //reason for elimination
public:
Vote() { voted = ""; reason = ""; } //constructor without parameters
Vote(string player, string reason) { voted = player; this -> reason = reason;} //constructor with parameters (this one is used)
~Vote() { cout << "Vote object destroyed" << endl; }; //destructor
string getVotedPlayer() { return voted; } //getters
string getReason() { return reason; }
void setVotedPlayer(string player) { voted = player; } //setters
void setReason(string reason) { this -> reason = reason; }
void status() { cout << "Voted player: " << voted << endl << "Reason: " << reason << endl;} //status function
};
#endif // VOTE_H_INCLUDED
原因是您有一个包含 4 个元素的数组(因此只有索引 0..3 是有效的)并且您允许自己使用 5 个可能的值 (0..4) 对其进行索引,其中 4 是不是有效索引。
这里是数组的定义:
字符串原因[4] = {"Den ta pame kala metaxi mas", "Einai ikanoteros/i apo emena kai ton/ti theoro apeili", "Den exei na prosferei kati stin omada", "Prospathei sinexeia na sampotarei tis prospatheies mas"};
这里是指数的选择:
reasonIndex = rand() % 5;
这是该索引的用法:
draft.setReason(原因[原因索引]);
这就是为什么您在 basic_string::_M_create 中看到错误的原因,因为您正在复制一个您不知道实际上是字符串的值。
在设置 reasonIndex 的行中,只需将 5 更改为 4。
我正在做一项作业,要求我们为真人游戏模拟 'elimination voting' 程序。为此,我们使用一个 class (Vote
) 来记录要淘汰的玩家的名字,另一个 (Voting
) 不会在任何地方实例化,因为它的成员是静态的 (我们需要他们)。选票存储在 Voting class.
问题是,即使我使用 push_back
函数将选票存储在向量中,在 运行 程序几次后,我得到一个 std::length_error
和 what(): basic_string::_M_create
。在我关闭它并重新运行后,我第一次收到如标题中的错误 (std::bad_alloc
)。
有什么想法吗?我怀疑它与 vector 没有正确释放内存有关,但我不确定。
我的代码(Voting.h):
#ifndef VOTING_H_INCLUDED
#define VOTING_H_INCLUDED
#include <vector>
#include <map>
#include "Vote.h" //ignore this one
#include "Team.h" //this one too
class Voting
{
public:
static vector <Vote> votes; //votes cast during voting procedure
static map <string, int> results; //voting results (key: name, value: number of votes)
static void votingProcess(Team &team); //the whole voting procedure
};
#endif // VOTING_H_INCLUDED
Voting.cpp:
#include <vector>
#include <map>
#include <cstdlib>
#include "Vote.h"
#include "Voting.h"
using namespace std;
vector <Vote> Voting::votes(1); //initialize the vector for the votes
void voteCast(Team &team);
void Voting::votingProcess(Team &team)
{
voteCast(team);
}
void voteCast(Team &team)
{
int playerNumber = team.getNumberOfPlayers(); //number of players right now still in the team
int votingPlayer = 0; //index of the currently voting player
int votedPlayerIndex = -1; //index of the player to be voted for elimination
int reasonIndex = -1; //index of the selected reason for voting
Vote draft; //temporary empty vote
srand(time(NULL)); // initialize the RNG
Voting::votes.clear(); //clear the vector of any past votes
string reasons[4] = {"Den ta pame kala metaxi mas", "Einai ikanoteros/i apo emena kai ton/ti theoro apeili", "Den exei na prosferei kati stin omada", "Prospathei sinexeia na sampotarei tis prospatheies mas"};
//some reasons for elimination (i've tried smaller strings and even chars and it didn't work, so don't bother)
do
{
if (team.getPlayers()[votingPlayer].getAge() != 0 && team.getPlayers()[votingPlayer].getVotes() > 0)
//if the player with index votingPlayer has not been eliminated and has still votes to cast
{
do
{
votedPlayerIndex = rand() % 11; //select a random player for elimination
reasonIndex = rand() % 5; //select a random reason for it
}
while ((team.getPlayers()[votedPlayerIndex].getAge() == 0) || (votedPlayerIndex == votingPlayer) || (team.getPlayers()[votedPlayerIndex].getImmunity() == true));
// selection continues if the selected player has already been eliminated,
//if the selected player is the same as the voting player or if the selected player has immunity from elimination
team.getPlayers()[votingPlayer].setVotes(team.getPlayers()[votingPlayer].getVotes() - 1); //reduce the player's available votes by 1
draft.setVotedPlayer(team.getPlayers()[votedPlayerIndex].getName()); //write the name of the player to be voted in an empty Vote object
draft.setReason(reasons[reasonIndex]); //and the reason too
Voting::votes.push_back(draft); //push the Vote obj. in the vector
}
else
{
votingPlayer++; //ignore and get to the next player
}
}
while (votingPlayer < playerNumber); //vote casting continues until every player has casted a vote
}
Vote.h:
#ifndef VOTE_H_INCLUDED
#define VOTE_H_INCLUDED
#include <string>
#include <iostream>
using namespace std;
class Vote
{
string voted; //name of the player to be eliminated
string reason; //reason for elimination
public:
Vote() { voted = ""; reason = ""; } //constructor without parameters
Vote(string player, string reason) { voted = player; this -> reason = reason;} //constructor with parameters (this one is used)
~Vote() { cout << "Vote object destroyed" << endl; }; //destructor
string getVotedPlayer() { return voted; } //getters
string getReason() { return reason; }
void setVotedPlayer(string player) { voted = player; } //setters
void setReason(string reason) { this -> reason = reason; }
void status() { cout << "Voted player: " << voted << endl << "Reason: " << reason << endl;} //status function
};
#endif // VOTE_H_INCLUDED
原因是您有一个包含 4 个元素的数组(因此只有索引 0..3 是有效的)并且您允许自己使用 5 个可能的值 (0..4) 对其进行索引,其中 4 是不是有效索引。
这里是数组的定义:
字符串原因[4] = {"Den ta pame kala metaxi mas", "Einai ikanoteros/i apo emena kai ton/ti theoro apeili", "Den exei na prosferei kati stin omada", "Prospathei sinexeia na sampotarei tis prospatheies mas"};
这里是指数的选择:
reasonIndex = rand() % 5;
这是该索引的用法:
draft.setReason(原因[原因索引]);
这就是为什么您在 basic_string::_M_create 中看到错误的原因,因为您正在复制一个您不知道实际上是字符串的值。
在设置 reasonIndex 的行中,只需将 5 更改为 4。