【问题标题】:How can I figure out where and why this segmentation fault occurs?我怎样才能弄清楚这个分段错误发生的位置和原因?
【发布时间】:2012-04-27 17:40:45
【问题描述】:

我无法找出我的代码的问题...我正处于游戏原型设计的早期阶段(我的第一个严肃项目)。它经常(但并非总是)因分段错误而崩溃。这是程序的流程......

  • 标题屏幕 - 按 z 开始新游戏
  • 屏幕上的玩家和敌人......敌人在碰撞时会夺走一条生命,有 4 条生命。
  • 当角色生命为 0 时,游戏返回标题画面 - 按 z 开始新游戏

最后一步是崩溃发生的地方...崩溃似乎只发生在玩家死亡并被带回标题屏幕并且玩家按 z 开始另一个游戏之后,但它并不总是崩溃。通过gdb,我确定它发生在调用Title的解构器时......

这是调试信息和相关代码...如果需要,我将提供任何其他代码/信息。

*** glibc detected *** /home/rzrscm/code/demogamething/game: free(): invalid pointer: 0x080c6b98 ***

//memory map info omitted

0xb7c54537 in raise () from /lib/libc.so.6
(gdb) where
#0  0xb7c54537 in raise () from /lib/libc.so.6
#1  0xb7c57922 in abort () from /lib/libc.so.6
#2  0xb7c8afbd in ?? () from /lib/libc.so.6
#3  0xb7c950ca in ?? () from /lib/libc.so.6
#4  0xb7c96918 in ?? () from /lib/libc.so.6
#5  0xb7c99a5d in free () from /lib/libc.so.6
#6  0xb7f4e776 in SDL_FreeSurface () from /usr/lib/libSDL-1.2.so.0
#7  0x0804ac7f in ~Title (this=0x80b4250, __in_chrg=<value optimized out>) at title.cpp:13
#8  0x08049d3a in GameState::load (this=0x804e368, loadState=LEVEL) at gamestate.cpp:39
#9  0x08049c5c in GameState::change (this=0x804e368, changeTo=LEVEL) at gamestate.cpp:26
#10 0x08049753 in Player::handleEvent (this=0x804e300) at player.cpp:102
#11 0x080490c8 in main () at main.cpp:27

所以,我所知道的是,当它将状态从 TITLE 更改为 LEVEL 时会发生崩溃...这是卸载和加载状态的类函数...currentState 是 GameState 类中的私有向量...

std::vector<GameState *> currentState;

void GameState::load(STATE loadState) {
    if(state == TITLE) {
        while(!currentState.empty()) {
            delete currentState.back();
            currentState.pop_back();
        }
        currentState.push_back(new Title()); 
    }
    else if(state == LEVEL) {
        while(!currentState.empty()) {
            delete currentState.back();
            currentState.pop_back();
        }
        currentState.push_back(new Level(currentLevel));
   }
}

当调用 Title 类的解构函数时会发生崩溃...无论是释放音乐还是图像都会发生这种情况...无论哪个是第一个函数,它都会崩溃。

Title::~Title() {
    SDL_FreeSurface(background);
    Mix_FreeMusic(music);
    background = NULL;
    music = NULL;
}

这是图片加载功能的代码...

SDL_Surface *loadImage(std::string imageFile) { 
    SDL_Surface *loadedImage;
    SDL_Surface *newImage; 

    loadedImage = IMG_Load(imageFile.c_str()); 
    newImage = SDL_DisplayFormatAlpha(loadedImage); 

    SDL_FreeSurface(loadedImage); 

    return newImage; 

}

[edit] 我在调试器中运行了几次,但没有对代码进行任何更改,因为我仍然找不到问题所在……而且每次在尝试释放音乐时发生崩溃……

0xb7c54537 in raise () from /lib/libc.so.6
(gdb) backtrace
#0  0xb7c54537 in raise () from /lib/libc.so.6
#1  0xb7c57922 in abort () from /lib/libc.so.6
#2  0xb7c8afbd in ?? () from /lib/libc.so.6
#3  0xb7c950ca in ?? () from /lib/libc.so.6
#4  0xb7c9633e in ?? () from /lib/libc.so.6
#5  0xb79974e2 in ?? () from /usr/lib/libmikmod.so.2
#6  0xb7997640 in Player_Free () from /usr/lib/libmikmod.so.2
#7  0xb7ebb6e3 in Mix_FreeMusic () from /usr/lib/libSDL_mixer-1.2.so.0
#8  0x0804ac8d in ~Title (this=0x80c6bc0, __in_chrg=<value optimized out>) at title.cpp:14
#9  0x08049d3a in GameState::load (this=0x804e368, loadState=LEVEL) at gamestate.cpp:39
#10 0x08049c5c in GameState::change (this=0x804e368, changeTo=LEVEL) at gamestate.cpp:26
#11 0x08049753 in Player::handleEvent (this=0x804e300) at player.cpp:102
#12 0x080490c8 in main () at main.cpp:27

【问题讨论】:

  • No...Level 和 Title 有自己的背景专用指针。
  • loadImageTitle 的构造函数中被调用?怎么样?
  • 背景 = loadImage("bg.png");
  • 你试过 valgrind 吗?
  • 不...我只是在使用 gdb...如果有帮助,我会试试 Valgrind。

标签: c++ segmentation-fault game-engine


【解决方案1】:
#5  0xb7c99a5d in free () from /lib/libc.so.6
#6  0xb7f4e776 in SDL_FreeSurface () from /usr/lib/libSDL-1.2.so.

您可能正在释放一个无效的指针。现在我读了

free(): invalid pointer: 0x080c6b98 

您可能正在尝试释放未动态分配的对象。 background如何获得他的价值?

【讨论】:

  • 这是我检查的第一件事......而且我找不到任何释放 NULL 指针的地方,至少不是以明显的方式。
  • 玩家快速连续输入两个或更多“Z”可能会触发该错误。因此,您正在尝试破坏尚未构建的东西。
  • 背景只是使用 background = loadImage("bg.png");在 Title 的构造函数中...
  • @James Anderson 我测试了 z 理论,这不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 2011-12-19
相关资源
最近更新 更多