运行代码时,我不断收到此错误。我不确定为什么会一直出现此错误,因为我在使用delete
运算符分配的两个对象上调用了new
。
我尝试在Xcode中运行它,但得到了thread 1: signal SIGABRT error
。
PokerV2.cpp
int main() {
bool game_flag = true;
Poker_Game game1;
game1.initialise_game();
game1.game_run();
while (game_flag) {
char input = 'a';
game_flag = false;
game1.game_run(game1.get_current_players());
std::cout << "Press 'y' to continue";
std::cin >> input;
if (input == 'y') {
game_flag = true;
}
}
}
poker_game_class.hpp
void Poker_Game::game_run() {
int lowest = 10;
int num = 0;
// Create the deck and table dynamically
Deck *deck = new Deck();
Table *table = new Table(_player_num);
deck->deal_cards(table->get_all_players(), _player_num, *table);
for (int i = 0; i < 4; i++) {
table->set_game_flag(i);
table->set_highest_bet(0);
for (int z = 0; z < table->get_player_num(); z++) {
table->players_turn(z);
}
}
for (int i = 0; i < table->get_player_num(); i++) {
if (table->get_player(i).calculate_score(*table) < lowest) {
num = i;
}
}
std::cout << "The winner is player: " << num << "\n";
std::cout << "The winner has won: £" << table->get_pot() << "\n";
//Add total pot to players cash
float current_balance = table->get_player(num).get_balance();
float balance_after_win = current_balance + table->get_pot();
table->get_player(num).set_balance(balance_after_win);
std::cout << "Winners balance: £" << table->get_player(num).get_balance();
this->Current_players = table->get_all_players();
delete deck;
delete table;
}
仅在删除game_run
和deck
时,table
函数中才会发生错误。
下面是链接的GitHub存储库
答案 0 :(得分:2)
您在这里遇到问题:
Player * Table::get_all_players()
{
return Players;
}
当调用此函数时,您将返回指向Poker_Game
的指针(和所有权):
// One place you call it from.
set_current_players(table -> get_all_players());
问题在于,两个对象现在都拥有Players
的所有权,并且都在它们拥有的指针上调用delete []
。
Poker_Game::~Poker_Game()
{
delete[] Current_players;
}
Table::~Table()
{
delete[] Players;
}
不说这是您唯一的错误。
您基本上已经陷入应用程序内部所有权错误的陷阱。在C ++中,我们通过使用特定的类型和语言构造来显式标记所有权来解决此问题(与C不同)。这样,我们可以明确知道谁拥有一个对象,从而由谁负责删除它们。
通过做两件事可以轻松解决您的问题。
std::vector<>
为您管理分配。一个简单的规则是“关注分离”。
一个类应该是业务逻辑或应该是资源管理。因此,您的类应该要么处理扑克的逻辑,要么应该处理管理分配的内存的逻辑(而不是两者)。因此,任何处理扑克事物的类都不应将new / delete称为处理new / delete的类。
现在,标准库提供了许多资源管理代码,因此您不需要,您只需使用现有代码并专注于扑克逻辑即可。如果在游戏运行后您确定标准资源管理效率不够高,则可以将其作为单独的任务集中精力进行升级。