【问题标题】:Receiving segmentation fault in C++ code在 C++ 代码中接收分段错误
【发布时间】:2011-10-26 21:37:40
【问题描述】:

我正在使用 C++、code::blocks(启用了警告并检查以确保)和 SFML。

我已经尝试自己寻找错误,但我真的找不到问题所在。我知道段错误是什么意思,但这个真的让我很难过。我是初学者,我可以补充一下,但我正在快速学习。

我有一个基本的主类void Engine,它有一个方法void RenderFrame,可以渲染应用程序的每一帧。在上述方法中,我有这段代码应该将所有图块绘制到渲染窗口上:

Tile* tile;    
for (short y = 0; y < mapHeight; ++y) {
    for (short x = 0; x < mapWidth; ++x) {
        tile    = currentLevel -> GetTile(x, y);

        if (tile) {
            tile -> Draw((x * tileSize), (y * tileSize), Wnd);
        }
    }
}

GetTile 方法应该从std::vector&lt;std::vector&lt;Tile *&gt; &gt; 中返回一个图块

Draw 方法只做这个:

void Tile::Draw(int x, int y, sf::RenderWindow *pWnd) {
    sprite.SetPosition(x, y);
    pWnd -> Draw(sprite);
}

应用程序编译得很好,但在调用 sprite.SetPosition(x, y); 后立即崩溃

这是来自调试器的完整调用堆栈:

#0 68701829 sf::Drawable::SetPosition(float, float) () (D:\Coding\C++\sfml\bin\debug\sfml-graphics.dll:??)
#1 004021F9 Tile::Draw(this=0x76ab8cd5, x=0, y=0, pWnd=0x3e3310) (D:\Coding\C++\sfml\include\Tile.cpp:12)
#2 00401D7E Engine::RenderFrame(this=0x3e3298) (D:\Coding\C++\sfml\include\Engine.cpp:106)
#3 00401B29 Engine::MainLoop(this=0x3e3298) (D:\Coding\C++\sfml\include\Engine.cpp:63)
#4 00401E27 _fu0___ZTIPKc(this=0x3e3298) (D:\Coding\C++\sfml\include\Engine.cpp:119)
#5 004022D6 main() (D:\Coding\C++\sfml\Main.cpp:8)

我希望这是足够的信息,并提前感谢。

编辑:哦,这是来自调试器的输出。 Program received signal SIGSEGV, Segmentation fault. In sf::Drawable::SetPosition(float, float) () 没有提供有关问题的更多信息。

【问题讨论】:

  • 你有sf::Drawable::SetPosition的代码吗? sprite 的定义是什么?调试器是否不允许您查看函数中崩溃的特定行?
  • 只是好奇:sprite 是 Sprite 还是 Sprite&?如果是第二个,你有没有可能不小心做了sprite = *((Sprite*)NULL);之类的事情?
  • 精灵是否比tilesize大(甚至1像素)?
  • 那个堆栈跟踪似乎与代码不匹配?例如,为什么在调用 SetPosition 之前引用了 cout 而没有引用您显示为代码的 Tile::Draw 方法。
  • David: sf::* 来自 SFML 库,我没有任何代码。 Luiscubal:精灵是 sf::Sprite sprite; Marty:tileSize 是 32,而 sprite 并没有变大。 Trojanfoe:哦,糟糕,我在 cout 中进行了一些快速测试,但在代码中删除了它。在一秒钟内更新堆栈跟踪。

标签: c++ segmentation-fault sfml


【解决方案1】:

回溯中的这一行看起来很可疑:

#1 004021F9 Tile::Draw(this=0x76ab8cd5, x=0, y=0, pWnd=0x3e3310) 

这似乎与您的 Tile::Draw 函数相对应,除了 this 指针未对齐,这表明它不是有效指针。所以也许你的std::vector&lt;std::vector&lt;Tile *&gt; &gt; 已经被某种方式损坏了。

【讨论】:

  • 天啊!我没有为std::vector&lt;std::vector&lt;Tile *&gt; &gt; 中的单元格创建默认磁贴,所以它们是……空的。通过循环遍历它为每个单元格创建一个空图块来修复它。
【解决方案2】:

最可能的解释是currentLevel-&gt;GetTile(x,y)返回的指针无效。这可能是因为它没有正确初始化(为 NUL 或有效分配的对象)或者因为它所引用的对象已被销毁。两者都会解释 sprite 不是一个有效对象,并且在该对象上调用 SetPosition 将传递一个无效的 this 指针,该指针将触发 SIGSEGV。

【讨论】:

  • 在此分配后检查空指针。但是,指针可能不为空,但仍然无效。
【解决方案3】:

分段错误的一般原因是取消引用空指针或无效指针。
1、检查GetTile(),是不是这个问题导致的?
2. 取消引用前检查currentLevel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2019-01-22
    相关资源
    最近更新 更多