取消引用指针时出现 SIGSEGV 分段错误
SIGSEGV Segmentation Fault when dereferencing a pointer
我知道已经有几个与此类似的问题,但我已经通读了它们,其中 none 似乎涵盖了我的具体问题...
我正在尝试从结构中取消引用 public 指针,但它抛出了 SIGSEV 分段错误,即使指针确实指向一个值
它打印了 1 和 2 但没有进一步打印。如果我将其更改为引用指针而不是值,错误将移动到我引用该值的任何地方,所以我知道问题出在取消引用上,而不是该行的其余部分。
如果您需要查看我的更多代码以查找问题,请直接询问。我只是不想让您不必要地浏览数百行...
#include <vector>
#include "Entities.cpp"
struct Chunk {
public:
std::vector<BaseEntity>* environment; // this is what I'm trying to access
Chunk() {
environment = new std::vector<BaseEntity>(1); // this is where init
environment->push_back(Grass()); // adding something to it works fine
}
~Chunk() {
delete(environment);
}
};
class World {
public:
Chunk* loaded[3][3];
World() {
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++) {
loaded[x][y] = new Chunk();
}
}
~World() {
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++) {
delete(loaded[x][y]);
}
}
};
这是访问它的代码(在另一个 class 和文件中)
void render(SDL_Renderer* gRenderer, Atlas* atlas, World* world, int SCREEN_WIDTH, int SCREEN_HEIGHT) {
printf("1");
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++) {
printf("2");
std::vector<BaseEntity> env =
*(world->loaded[x][y]->environment); // here is where the error occurs
printf("3");
printf('0' + env.size() + "");
printf("a");
for (const auto& a : env) {
printf("b");
drawTexture(gRenderer, atlas, a.atlasID,
SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
}
printf("4");
}
printf("5");
}
这是调用它的代码:
int main(int argv, char** args) {
SDL_Init( SDL_INIT_VIDEO );
//The window we'll be rendering to
SDL_Window* gWindow = SDL_CreateWindow(
title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if (gWindow == NULL) {
printf("window error");
}
//Create renderer for window
SDL_Renderer* gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if (gRenderer == NULL) {
printf("renderer error");
}
bool quit = false; // quit flag
//Event handler
SDL_Event e;
//nice little rendering class
Renderer* renderer = new Renderer();
//World
World* world = new World();
//Texture Atlas
Atlas* atlas = new Atlas(SDL_GetWindowSurface( gWindow), gRenderer);
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
switch(e.type) {
case SDL_QUIT: //User requests quit
quit = true;
break;
}
}
//Clear screen
//SDL_SetRenderDrawColor( gRenderer, 0, 0xFF, 0, 0xFF );
SDL_RenderClear( gRenderer );
renderer->render(gRenderer, atlas, world, SCREEN_WIDTH, SCREEN_HEIGHT);
//Update the surface
SDL_RenderPresent(gRenderer);
//SDL_UpdateWindowSurface( gWindow );
}
delete (world, renderer, atlas);
return 0;
}
我没有发现您的代码有直接问题(除了复制向量显然效率低下),但我 发现您的 printf
调试有问题.
- 您应该使用
fprintf(stderr, ...)
进行调试 printf
s,以避免 stdio 缓冲,或调用 fflush(NULL)
.
3
未打印的事实并不一定意味着 printf("3")
未达到。
- 您应该完全避免
printf
调试,并学会使用真正的调试器(GDB 或 LLDB)。
- 如果您 运行 您的程序带有 Address Sanitizer (
-fsanitize=address
);它可能会直接指出错误。
最后,在C++
中书写时,避免使用C
风格的数组,尤其是多级数组。请改用 vector
s。
这分配了一个 std::vector 和 BaseEntity
的一个元素
environment = new std::vector<BaseEntity>(1); // this is where init
然后附加 Grass
的另一个元素
environment->push_back(Grass()); // adding something to it works fine
但也许这是第一个问题,因为向量只包含 BaseEntity
s,参见 What is object slicing?
这会访问给定向量的第一个元素,这不是附加的 Grass
而是 new std::vector<BaseEntity>(1)
中默认构造的 BaseEntity
对象
std::vector<BaseEntity> env = *(world->loaded[x][y]->environment); // here is where the error occurs
访问指针应该没有问题,因为它似乎已正确初始化。
但也许复制 BaseEntity
才是真正的问题。我会查看 BaseEntity
(可能还有 Grass
)的(复制)构造函数,看看是否存在一些有问题的代码。
我知道已经有几个与此类似的问题,但我已经通读了它们,其中 none 似乎涵盖了我的具体问题...
我正在尝试从结构中取消引用 public 指针,但它抛出了 SIGSEV 分段错误,即使指针确实指向一个值
它打印了 1 和 2 但没有进一步打印。如果我将其更改为引用指针而不是值,错误将移动到我引用该值的任何地方,所以我知道问题出在取消引用上,而不是该行的其余部分。
如果您需要查看我的更多代码以查找问题,请直接询问。我只是不想让您不必要地浏览数百行...
#include <vector>
#include "Entities.cpp"
struct Chunk {
public:
std::vector<BaseEntity>* environment; // this is what I'm trying to access
Chunk() {
environment = new std::vector<BaseEntity>(1); // this is where init
environment->push_back(Grass()); // adding something to it works fine
}
~Chunk() {
delete(environment);
}
};
class World {
public:
Chunk* loaded[3][3];
World() {
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++) {
loaded[x][y] = new Chunk();
}
}
~World() {
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++) {
delete(loaded[x][y]);
}
}
};
这是访问它的代码(在另一个 class 和文件中)
void render(SDL_Renderer* gRenderer, Atlas* atlas, World* world, int SCREEN_WIDTH, int SCREEN_HEIGHT) {
printf("1");
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++) {
printf("2");
std::vector<BaseEntity> env =
*(world->loaded[x][y]->environment); // here is where the error occurs
printf("3");
printf('0' + env.size() + "");
printf("a");
for (const auto& a : env) {
printf("b");
drawTexture(gRenderer, atlas, a.atlasID,
SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
}
printf("4");
}
printf("5");
}
这是调用它的代码:
int main(int argv, char** args) {
SDL_Init( SDL_INIT_VIDEO );
//The window we'll be rendering to
SDL_Window* gWindow = SDL_CreateWindow(
title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if (gWindow == NULL) {
printf("window error");
}
//Create renderer for window
SDL_Renderer* gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if (gRenderer == NULL) {
printf("renderer error");
}
bool quit = false; // quit flag
//Event handler
SDL_Event e;
//nice little rendering class
Renderer* renderer = new Renderer();
//World
World* world = new World();
//Texture Atlas
Atlas* atlas = new Atlas(SDL_GetWindowSurface( gWindow), gRenderer);
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
switch(e.type) {
case SDL_QUIT: //User requests quit
quit = true;
break;
}
}
//Clear screen
//SDL_SetRenderDrawColor( gRenderer, 0, 0xFF, 0, 0xFF );
SDL_RenderClear( gRenderer );
renderer->render(gRenderer, atlas, world, SCREEN_WIDTH, SCREEN_HEIGHT);
//Update the surface
SDL_RenderPresent(gRenderer);
//SDL_UpdateWindowSurface( gWindow );
}
delete (world, renderer, atlas);
return 0;
}
我没有发现您的代码有直接问题(除了复制向量显然效率低下),但我 发现您的 printf
调试有问题.
- 您应该使用
fprintf(stderr, ...)
进行调试printf
s,以避免 stdio 缓冲,或调用fflush(NULL)
.
3
未打印的事实并不一定意味着printf("3")
未达到。 - 您应该完全避免
printf
调试,并学会使用真正的调试器(GDB 或 LLDB)。 - 如果您 运行 您的程序带有 Address Sanitizer (
-fsanitize=address
);它可能会直接指出错误。
最后,在C++
中书写时,避免使用C
风格的数组,尤其是多级数组。请改用 vector
s。
这分配了一个 std::vector 和 BaseEntity
environment = new std::vector<BaseEntity>(1); // this is where init
然后附加 Grass
的另一个元素
environment->push_back(Grass()); // adding something to it works fine
但也许这是第一个问题,因为向量只包含 BaseEntity
s,参见 What is object slicing?
这会访问给定向量的第一个元素,这不是附加的 Grass
而是 new std::vector<BaseEntity>(1)
BaseEntity
对象
std::vector<BaseEntity> env = *(world->loaded[x][y]->environment); // here is where the error occurs
访问指针应该没有问题,因为它似乎已正确初始化。
但也许复制 BaseEntity
才是真正的问题。我会查看 BaseEntity
(可能还有 Grass
)的(复制)构造函数,看看是否存在一些有问题的代码。