尝试删除priority_queue元素时使用'std :: bad_alloc'C ++

时间:2019-05-20 02:54:44

标签: c++ qt bad-alloc

将船只返回港口时,速度变为0.0,用户输入防护罩和燃料。

–如果燃料为0.0,则船只将被摧毁

–仍在优先队列中的船只会受到10点盾牌伤害并损失15点燃油

–如果护盾或燃料小于0.0,则船只将被摧毁

尝试为我的最终项目实施这些说明。这些飞船是指针类型,它们位于名为“战场”的优先级队列中。这些船也存在于称为“端口”的指针列表中。我试图摧毁遭受致命伤害的船只,但是当我试图向他们展示时,Qt程序崩溃并且我得到bad_alloc错误。这是我要做的最后一件事:(

来自各种文件的重要代码块:

我已经尝试从港口删除船只,还尝试直接从港口删除船只,但是priority_queue搞砸了。

class Civilization {
string name;
int x;
int y;
list<Villager> villagers;
list<Ship*> port;
priority_queue<Ship*, vector<Ship*>, Ship::comp> battle;
}


void Civilization::damageShips()
{
priority_queue<Ship*, vector<Ship*>, Ship::comp> copy = battle;
Ship *s = battle.top();
s->setSpeed(0.0);

while(!copy.empty()) {
    Ship *s = copy.top();
    s->setShield(s->getShield() - 10);
    s->setFuel(s->getFuel() - 15);
    copy.pop();
}


priority_queue<Ship*, vector<Ship*>, Ship::comp> temp;

while(!copy.empty()) {
    Ship *s = copy.top();
    string id = s->getId();

    if (s->getShield() > 0 && s->getFuel() > 0) {
        temp.push(s);
    } else
        deleteShip(id);
    copy.pop();
}


battle = temp;
battle.pop();
}

void battlefielddisplay::setCivilization(Civilization *civilizaition)
{
size_t size = civilizaition->battlefieldSize();
ui->battlefield_table->setRowCount(int(size));

Civilization &c = *civilizaition;

priority_queue<Ship*, vector<Ship*>, Ship::comp> copy = c.getBattlefield();

int cnt = 0;
while(!copy.empty()) {
    Ship *s = copy.top();

    QString id = QString::fromStdString(s->getId());
    QString fuel = QString::number(s->getFuel());
    QString speed = QString::number(s->getSpeed());
    QString shield = QString::number(s->getShield());
    QString warriors = QString::number(s->size());

    QTableWidgetItem *idItem = new QTableWidgetItem(id);
    QTableWidgetItem *fuelItem = new QTableWidgetItem(fuel);
    QTableWidgetItem *speedItem = new QTableWidgetItem(speed);
    QTableWidgetItem *shieldItem = new QTableWidgetItem(shield);
    QTableWidgetItem *warriorsItem = new QTableWidgetItem(warriors);

    ui->battlefield_table->setItem(cnt, 0, idItem);
    ui->battlefield_table->setItem(cnt, 1, fuelItem);
    ui->battlefield_table->setItem(cnt, 2, speedItem);
    ui->battlefield_table->setItem(cnt, 3, shieldItem);
    ui->battlefield_table->setItem(cnt, 4, warriorsItem);

    cnt++;

    copy.pop();
}

}

void MainWindow::on_battle_remove_ship_clicked()
{
if (flag) {
    Civilization* c = videogame.searchCivilization(ui->civilization_search_input->text().toStdString());

    double shield = ui->shield_battle_remove->value();
    double fuel = ui->fuel_battle_remove->value();

    Ship *s = c->getBattleShip();
    s->setSpeed(0.0);
    s->setShield(shield);
    s->setFuel(fuel);

    c->damageShips();

    qDebug() << "[✔]" << "Removed ship from battlefield";

} else
    QMessageBox::information(this, "Error", "Civilization not found");
}

bool Civilization::deleteShip(string &id)
{
bool found = false;
for(size_t i(0); i < shipSize(); ++i) {
    auto it = port.begin();
    advance(it, i);
    auto x = *it;
    if (x->getId() == id) {
        port.erase(it);
        delete x;
        --i;
        found = true;
    }
}
return found;
}

1 个答案:

答案 0 :(得分:0)

我看到的主要问题是您删除了对象却没有从容器中删除指针。您要重复访问同一容器多次,并尝试访问已删除的对象。

另一个问题是您有同一队列的多个副本,因此即使从主容器中删除指针也可能会导致问题。

尝试重新考虑算法,特别注意对象的生命周期。例如,您可能有一个懒惰的删除:不是删除而是将对象标记为以后将要删除的对象。您可能会在功能结束时进行清理。

相关问题