为什么调试器抛出 "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{};
没有创建 Snake
。 snake
是指向 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
相同的数值(这些在汇编级别都是相同的)。
要解决此问题,您需要在使用完后使用 new
和 delete
在堆上分配一个 Snake 实例,或者通过删除在堆栈上分配实例指针。
第一次在这里发帖,如果这是初学者的问题,请见谅。我正在尝试为我正在制作的简单游戏创建 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{};
没有创建 Snake
。 snake
是指向 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
相同的数值(这些在汇编级别都是相同的)。
要解决此问题,您需要在使用完后使用 new
和 delete
在堆上分配一个 Snake 实例,或者通过删除在堆栈上分配实例指针。