为什么调试器抛出 "read access violation. this was nullptr" 异常?

Why is the debugger throwing "read access violation. this was nullptr" exception?

第一次在这里发帖,如果这是初学者的问题,请见谅。我正在尝试为我正在制作的简单游戏创建 Snake class,但调试器不断抛出奇怪的异常。

每次我调试程序时,它都会带我进入一个 'vector' 文件,指向某一行并说:"read access violation.'this' was nullptr"。当我 运行 它没有调试它只是以消息终止时: "exited with code -1073741819."。

几个小时以来我一直在尝试解决这个问题,但仍然不知道问题出在哪里。是我的代码有问题,还是问题不在于此?提前致谢!

在Snake.h中:

#include <vector>

class Snake{
private:
    std::vector<sf::RectangleShape> body;
    int speed;
public:
    Snake();

    void draw_body(sf::RenderWindow& windowRef);
    void move(sf::RenderWindow& windowRef);

    void set_speed(int s);

};

在Snake.cpp中:(我还没有完成Snake::move())

#include "Snake.h"
#include <SFML\Graphics.hpp>

Snake::Snake() : speed{ 10 }, body{ sf::RectangleShape { sf::Vector2f(50.f,50.f) } }{
    body.at(0).setPosition(50.f, 50.f);
}
void Snake::draw_body(sf::RenderWindow& windowRef) {
    for (sf::RectangleShape rect : body) {
        windowRef.draw(rect);
    }
}
void Snake::set_speed(int s) {
    speed = s;
}
void Snake::move(sf::RenderWindow& windowRef) {
    ;
}

在main.cpp中:

#include <SFML\Graphics.hpp>
#include <iostream>

#include "Snake.h"
class Snake;

int main() {
    sf::RenderWindow window(sf::VideoMode(800, 800), "MY window", sf::Style::Close | sf::Style::Titlebar);
    Snake* snake{};

    while (window.isOpen()) 
    {
        sf::Event event;

        while (window.pollEvent(event))
        {   
        }




        window.clear(sf::Color::White);

        snake->draw_body(window);

        window.display();




    }
    return 0;
}

这是因为您的代码具有未定义的行为 (UB)。它可以巧合地工作,也可以毫无征兆地失败,或者可能会发生最奇怪的事情。

调试器一般都特别小心,添加了很多控件。幸运的是,它发现了空指针的使用。事实上,这一行并不像你想象的那样:

Snake* snake{};

没有创建 Snakesnake 是指向 Snake 的指针。所以你刚刚初始化了一个指针。你认为它的价值是什么?

这里最好的选择是去掉指针:

Snake snake{};   // no *,  so now you have a real snake object ready to use

...
snake.draw_body(window);   // no ->  since it's no longer a pointer

这一行:

Snake* snake{};

不初始化Snake的一个实例class,而是一个指向实例的指针。指针在汇编级别是整数,默认情况下初始化为 0,与 C 中的 NULL 和现代 C++ 中的 nullptr 相同的数值(这些在汇编级别都是相同的)。

要解决此问题,您需要在使用完后使用 newdelete 在堆上分配一个 Snake 实例,或者通过删除在堆栈上分配实例指针。