【问题标题】:Vector invalid subscript. SFML向量无效下标。 SFML
【发布时间】:2020-09-19 00:43:14
【问题描述】:

我正在尝试制作一个蛇游戏,也许这个错误是一种可能的错误。因此,当我在调试和跨步时,我在向量的头文件中获得了指向异常的链接,并且在异常代码中写入了该向量的下标无效。 (错误原因可以通过vector bodyPart调用)。编译器消息:

snake.exe 中 0x00007FFA227EA799 处未处理的异常:Microsoft C++ 异常:内存位置 0x00000052FA7CDFD0 处的 std::out_of_range。

Snake::Snake(RenderWindow& window)
{
    bodyPart.setPosition(window.getSize().x / 4, window.getSize().y / 4);
    bodyPart.setSize(Vector2f(20.f, 20.f));
    bodyPart.setFillColor(Color(0, 0, 0));
    body.push_back(bodyPart);
}
//Sets default parameters
void Game::restart(RenderWindow& window)
{
    for (int i = 0; i < snake.body.size() - 1; i++)
    {
        snake.body.pop_back();
    }
    snake.bodyPart.setPosition(window.getSize().x / 4, window.getSize().y / 4);
    snake.body.push_back(snake.bodyPart);
}
//Updates game
void Game::tick(RenderWindow& window)
{
    if (snake.body.at(0).getPosition().x == fruit.fruitX && snake.body.at(0).getPosition().y == fruit.fruitY)
    {
        fruit.fruitX = fieldLCorn + rand() % fieldX * fieldY;
        fruit.fruitY = fieldLCorn + rand() % fieldY * fieldX;
        ui.score++;
        snake.body.reserve(1);
        snake.body.push_back(snake.bodyPart);
    }
}
void Game::moveSnake()
{
    switch(dir)
    {
    case 1:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(0, snake.body.at(0).getPosition().y + 10);
        snake.body.pop_back();
    case 2:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(0, snake.body.at(0).getPosition().y - 10);
        snake.body.pop_back();
    case 3:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(snake.body.at(0).getPosition().x + 10, 0);
        snake.body.pop_back();
    case 4:
        snake.body.push_back(snake.tail);
        snake.body.at(0).move(snake.body.at(0).getPosition().x - 10, 0);
        snake.body.pop_back();
    }
}
void Game::countCollision(RenderWindow& window)
{
    //Is snake met border
    if (snake.body.at(0).getPosition().x > 300) restart(window);
    if (snake.body.at(0).getPosition().y > 300) restart(window);
    if (snake.body.at(0).getPosition().x < -300) restart(window);
    if (snake.body.at(0).getPosition().y < -300) restart(window);
    //If snake eats itself
    for (int k = 0; k < snake.body.size() - 1; k++)
    {
        if (snake.body.at(0).getPosition().x == snake.body.at(k).getPosition().y && snake.body.at(0).getPosition().y == snake.body.at(k).getPosition().y)
        {
            restart(window);
        }
    }
}
void Game::render(RenderWindow& window)
{
    for (int i = 0; i < snake.body.size() - 1; i++)
    {
        window.draw(snake.body.at(i));
    }
}

【问题讨论】:

  • 您是否尝试在调试器中捕捉崩溃以查看它发生在代码中的时间和位置?使用的索引是什么?向量的大小是多少?你在说什么向量?请edit您的问题显示minimal reproducible example,重点是最小和完整位。如果它是可重复的,那是一个加号。
  • 另外,请致电srand一次。通过将其放入 Fruit 构造函数中,您创建的每个水果对象都将重置种子。如果您在一秒钟内执行两次(或更多),那么种子将被设置并重置为相同的值(因为time 通常返回具有秒分辨率的值)。
  • Microsoft C++ 异常,这意味着您可能正在使用 Visual Studio,您可以让它在发生这种情况的确切行处中断,以检查发生这种情况的位置以及为什么。
  • 我试图捕捉出错的行,但调试器只链接到头文件中的异常。好的,我会编辑。
  • 将“堆栈框架”组合框(在 Visual Studio 的工具栏上)更改为您的代码。这将向您显示导致问题的代码行。

标签: c++ exception vector sfml


【解决方案1】:

对于我在这里看到的,问题可能是

snake.body.at(0)

你在代码中使用了很多次,当主体没有元素时,所以没有 0 的元素

【讨论】:

  • 我在at() 中输入了 1 但这没有帮助。而且我认为这个向量有元素,因为我已经放了元素:body.push_back(bodyPart);
  • 1 显然不会有帮助,相反,您应该在代码中检查在某些情况下可以删除“bodyPart”@Vlad
  • 我在 at() 中输入了 1,但这无济于事。 如果有任何事情会使情况变得更糟的话。
【解决方案2】:

在您的Game::render() 函数中,循环条件显然会给出“越界”错误,因为在for (int i = 0; i &lt; snake.body.size() - 1; i++) 中它将尝试访问最后一个元素之后的 1。因此,您应该检查&lt;= 或删除-1(建议)。

【讨论】:

    【解决方案3】:

    所以我通过在主体容器中添加头部部分并使用不带参数的构造函数来解决问题,我还删除了不需要的向量大小检查(否)。这是我的新代码:

    Snake::Snake()
    {
        body.reserve(4);
        head.setPosition(400, 400);
        head.setSize(Vector2f(20.f, 20.f));
        head.setFillColor(Color(0, 0, 0));
        body.push_back(head);
        for (int i = 0; i < 3; i++)
        {
            bodyPart.setPosition(body.at(i).getPosition().x - 20, body.at(i).getPosition().y - 20);
            bodyPart.setSize(Vector2f(20.f, 20.f));
            bodyPart.setFillColor(Color(0, 0, 0));
            body.push_back(bodyPart);
        }
    }
    void Game::restart()
    {
        for (unsigned int i = 0; i < snake.body.size(); i--)
        {
            snake.body.pop_back();
        }
        snake.head.setPosition(400, 400);
    }
    void Game::tick()
    {
        moveSnake();
        if (snake.body.at(0).getPosition().x == fruit.fruitX && snake.body.at(0).getPosition().y == fruit.fruitY)
        {
            snake.body.reserve(1);
            for (unsigned int i = snake.body.size() - 1;i > 0;i--)
            {
                snake.body.at(i).setPosition(snake.body.at(i - 1).getPosition().x - 20, snake.body.at(i - 1).getPosition().y - 20);
            }
        }
        countCollision();
    }
    void Game::moveSnake()
    {
        switch(dir)
        {
        case 1:
            snake.body.push_back(snake.bodyPart);
            snake.body.at(0).move(0, snake.body.at(0).getPosition().y + 10);
            snake.body.pop_back();
        case 2:
            snake.body.push_back(snake.bodyPart);
            snake.body.at(0).move(0, snake.body.at(0).getPosition().y - 10);
            snake.body.pop_back();
        case 3:
            snake.body.push_back(snake.bodyPart);
            snake.body.at(0).move(snake.body.at(0).getPosition().x + 10, 0);
            snake.body.pop_back();
        case 4:
            snake.body.push_back(snake.bodyPart);
            snake.body.at(0).move(snake.body.at(0).getPosition().x - 10, 0);
            snake.body.pop_back();
        }
    }
    void Game::countCollision()
    {
        if (snake.body.size() >= 5)
        {
            //If snake eats itself
            for (unsigned int k = 1; k < snake.body.size(); k++)
            {
                if (snake.body.at(0).getPosition().x == snake.body.at(k).getPosition().y && snake.body.at(0).getPosition().y == snake.body.at(k).getPosition().y)
                {
                    restart();
                }
            }
        }
    }
    void Game::render(RenderWindow& window)
    {
        for (int i = 0; i < snake.body.size(); i++)
        {
            window.draw(snake.body.at(i));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-23
      • 2021-10-23
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 2014-10-03
      相关资源
      最近更新 更多