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



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

每次我调试程序时,它都会将我带入一个"矢量"文件,将我指向某一行并说:"读取访问冲突。当我在没有调试的情况下运行它时,它只是以消息终止:"使用 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 <SFMLGraphics.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) {
;
}

在主要.cpp:

#include <SFMLGraphics.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 类的实例,而是初始化指向实例的指针。指针是程序集级别的整数,默认情况下初始化为 0,与 C 中的NULL和现代C++中的nullptr相同的数值(它们在程序集级别都是相同的(。

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

相关内容

最新更新