【问题标题】:command push_back results an exit code -1073741819 (0xC0000005) c++命令 push_back 导致退出代码 -1073741819 (0xC0000005) c++
【发布时间】:2021-09-03 10:36:29
【问题描述】:

我正在尝试使用 c++ 制作一个小游戏,我必须将角色从地图上的一个点移动到另一个点。当我尝试通过 push_back 执行此操作然后从源点擦除时,我得到此退出代码。我究竟做错了什么? 我的移动代码是:

void Game::move(const GridPoint & src_coordinates, const GridPoint & dst_coordinates) {
    if(checkIfLegalCell(this, src_coordinates) == false ||
       checkIfLegalCell(this, dst_coordinates) == false) {
        throw IllegalCell();
    }
    if(searchInGrid(this->grid_characters, src_coordinates) == false){
        throw CellEmpty();
    }

    std::vector<Pair>::iterator it_src=this->grid_characters.begin();
    for(;it_src != this->grid_characters.end() ; ++it_src){
        if((*it_src).grid_point == src_coordinates){
            break;
        }
    }

    if( ((*it_src).character)->checkIfCanMove(src_coordinates, dst_coordinates) == false) {
        throw MoveTooFar();
    }

    if(searchInGrid(this->grid_characters, dst_coordinates) == true){
        throw CellOccupied();
    }

    this->grid_characters.push_back(Pair(dst_coordinates,(*it_src).character));
    this->grid_characters.erase(it_src);

}

    

我的主要看起来像这样:

#include <iostream>

#include <cassert>

#include "Exceptions.h"
#include "Game.h"

using namespace mtm;

void example1() {
    std::cout << "------example 1------" << std::endl;
    Game g1(8,8);
    g1.addCharacter(GridPoint(1,1), Game::makeCharacter(CharacterType::MEDIC, Team::POWERLIFTERS, 10, 2, 4, 5));
    g1.addCharacter(GridPoint(1,4), Game::makeCharacter(CharacterType::SNIPER, Team::POWERLIFTERS, 10, 2, 4, 5));
    g1.addCharacter(GridPoint(6,1), Game::makeCharacter(CharacterType::SOLDIER, Team::CROSSFITTERS, 10, 2, 4, 5));
    g1.addCharacter(GridPoint(6,4), Game::makeCharacter(CharacterType::MEDIC, Team::CROSSFITTERS, 10, 2, 4, 5));
    std::cout << g1 << std::endl;
    g1.move(GridPoint(1,1), GridPoint(1,2));
    std::cout << g1 << std::endl;
    std::cout << "Nice!" << std::endl;
}

int main() {
    example1();

    return 0;
}

打印出来:

C:\Users\User\CLionProjects\gameMakerCurr.1\cmake-build-debug\ex0.exe
------example 1------
*****************
| | | | | | | | |
| |M| | |N| | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| |s| | |m| | | |
| | | | | | | | |
*****************

Process finished with exit code -1073741819 (0xC0000005)

这是“游戏”的一部分,我用来创建-(坐标,字符)对

struct Pair {
        GridPoint grid_point;
        std::shared_ptr<Character> character;
        Pair(GridPoint grid_point, std::shared_ptr<Character> character) :
                grid_point(grid_point), character(character) {}
    };

    class Game {
        std::vector<Pair> grid_characters; //  character by grid point ; key = grid_point ; value = character.
        int height;
        int width;

关于如何解决此问题的任何提示?

【问题讨论】:

  • 如果循环退出而没有中断和it_src == this-&gt;grid_characters.end() 怎么办?
  • push_back 可以使插入向量的迭代器失效(如果需要调整大小)。
  • 我剪掉了这部分代码,但是我事先检查一切都很好,有一个角色,并且目的地在地图中并且是空的
  • 如果it_srcend(),你不能做*it_src
  • 编程专家提示:如果您知道某个条件不会发生,但会导致错误,请输入断言、错误消息、提前返回或任何东西。否则,其他开发人员和优秀的 stackoverflow 贡献者会指出这一点,从而导致您和他们浪费时间。

标签: c++ methods memory-management exit


【解决方案1】:

如果你仔细看,在程序中你试图将角色推到最后:

    this->grid_characters.push_back(Pair(dst_coordinates,(*it_src).character));
    this->grid_characters.erase(it_src);

首先,在向量中推入一个新元素后,它可能会重新分配数据以有足够的容量容纳更多元素。因此,在 push_back 之后,向量将数据移动到内存中的新位置。之后,尝试使用仍然指向 push_back 之前的位置的 it_src 进行擦除。
因此,在执行此操作之前,以及在计算 it_src 之前,您必须确保 vector 有足够的容量并且不会重新定位您的数据

   if (this->grid_characters.capacity() <= this->grid_characters.size())
       this->grid_characters.reserve(this->grid_characters.size() + 10);
       //other variants
       //this->grid_characters.reserve(this->grid_characters.size() + 1);
       //this->grid_characters.reserve(this->grid_characters.size() * 2);

这应该可以解决故障。


但从逻辑上讲,您为什么要尝试将对象移动到最后?您将坐标从 1,1 更改为 1,2。在向量中,它将位于坐标为 6,4 的对象之后。看起来向量中的顺序无关紧要。如果对象的顺序没有多大意义,那么只改变坐标而不在向量内移动它是有意义的

    it_src->grid_point = dst_coordinates;

如果顺序很重要,请使用 set。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2018-11-10
    • 2020-06-13
    • 2020-01-17
    相关资源
    最近更新 更多