malloc:***对象错误:未分配要释放的指针

时间:2019-07-08 15:37:51

标签: c++ malloc new-operator delete-operator

运行代码时,我不断收到此错误。我不确定为什么会一直出现此错误,因为我在使用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_rundeck时,table函数中才会发生错误。

The output from the terminal

下面是链接的GitHub存储库

https://github.com/mbh1620/PokerV2/tree/master/PokerV2

1 个答案:

答案 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不同)。这样,我们可以明确知道谁拥有一个对象,从而由谁负责删除它们。

通过做两件事可以轻松解决您的问题。

  1. 不要动态分配数组。
    使用std::vector<>为您管理分配。
  2. 不要动态分配寿命不超过函数的对象。
    只需使用局部变量,然后让范围规则对其进行处理即可。
  3. 如果必须动态分配对象,请使用智能指针。
    std :: unique_ptr和std :: shared_ptr很好地管理了分配对象的内存。
  4. 如果将一个对象传递给另一个对象(而不是传递所有权),则按引用(而不是指针)传递。
    这告诉另一个类,他们不拥有该对象,因此不应删除该对象。

一个简单的规则是“关注分离”。

一个类应该是业务逻辑或应该是资源管理。因此,您的类应该要么处理扑克的逻辑,要么应该处理管理分配的内存的逻辑(而不是两者)。因此,任何处理扑克事物的类都不应将new / delete称为处理new / delete的类。

现在,标准库提供了许多资源管理代码,因此您不需要,您只需使用现有代码并专注于扑克逻辑即可。如果在游戏运行后您确定标准资源管理效率不够高,则可以将其作为单独的任务集中精力进行升级。