【问题标题】:C++ SFML Game - Aborted (core dumped)C++ SFML 游戏 - 中止(核心转储)
【发布时间】:2018-06-12 15:17:24
【问题描述】:

我正在尝试“Beginning C++ Game Programming”中的代码,当我尝试运行该程序时,我得到“Aborted(core dumped)”。我怀疑问题出在指针上,但我不知道如何处理它。我不会在这里发布我所有的代码,因为它真的很长,所以如果缺少某些东西,我会添加其余的。这是我的代码:

LevelManager.cpp

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "textureholder.h"
#include <sstream>
#include <fstream>
#include "levelmanager.h"

using namespace sf;
using namespace std;

int** LevelManager::nextLevel(VertexArray& rVaLevel){
    m_LevelSize.x = 0;
    m_LevelSize.y = 0;

    // Get the next level
    m_CurrentLevel++;
    if (m_CurrentLevel > NUM_LEVELS){
        m_CurrentLevel = 1;
    }

    // Load the appropriate level from a text file
    string levelToLoad;
    switch (m_CurrentLevel){
        case 1:
            levelToLoad = "levels/level1.txt";
            m_StartPosition.x = 100;
            m_StartPosition.y = 100;
            break;
        case 2:
            levelToLoad = "levels/level2.txt";
            m_StartPosition.x = 100;
            m_StartPosition.y = 3600;
            break;
        case 3:
            levelToLoad = "levels/level3.txt";
            m_StartPosition.x = 1250;
            m_StartPosition.y = 0;
            break;
        case 4:
            levelToLoad = "levels/level4.txt";
            m_StartPosition.x = 50;
            m_StartPosition.y = 200;
            break;
    }
    ifstream inputFile(levelToLoad);
    string s;

    while(getline(inputFile, s)){
        ++m_LevelSize.y;
    }

    m_LevelSize.x = s.length();

    inputFile.clear();
    inputFile.seekg(0, ios::beg);

    int** arrayLevel = new int*[m_LevelSize.y];
    for (int i =0; i < m_LevelSize.y; ++i){
        arrayLevel[i] = new int[m_LevelSize.x];
    }

    string row;
    int y =0;
    while (inputFile >> row){
        for (int x = 0; x < row.length(); x++){
            const char val = row[x];
            arrayLevel[y][x] = atoi(&val);
        }
        y++;
    }
    inputFile.close();


    // What type of primitive are we using?
    rVaLevel.setPrimitiveType(Quads);
    // Set the size of the vertex array
    rVaLevel.resize(m_LevelSize.x * m_LevelSize.y * VERTS_IN_QUAD);
    // Start at the beginning of the vertex array
    int currentVertex = 0;
    for (int x = 0; x < m_LevelSize.x; x++){
        for (int y = 0; y < m_LevelSize.y; y++){

        // Position each vertex in the current quad
        rVaLevel[currentVertex + 0].position =Vector2f(x * TILE_SIZE, y * TILE_SIZE);
        rVaLevel[currentVertex + 1].position = Vector2f((x * TILE_SIZE) + TILE_SIZE , y * TILE_SIZE);
        rVaLevel[currentVertex + 2].position = Vector2f((x * TILE_SIZE) + TILE_SIZE , (y * TILE_SIZE) + TILE_SIZE);
        rVaLevel[currentVertex + 3].position =Vector2f((x * TILE_SIZE),(y * TILE_SIZE) + TILE_SIZE);

        // Which tile from the sprite sheet should we use
        int verticalOffset = arrayLevel[y][x] * TILE_SIZE;
        rVaLevel[currentVertex + 0].texCoords = Vector2f(0, 0 + verticalOffset);
        rVaLevel[currentVertex + 1].texCoords = Vector2f(TILE_SIZE, 0 + verticalOffset);
        rVaLevel[currentVertex + 2].texCoords = Vector2f(TILE_SIZE, TILE_SIZE + verticalOffset);
        rVaLevel[currentVertex + 3].texCoords = Vector2f(0, TILE_SIZE + verticalOffset);

        // Position ready for the next four vertices
        currentVertex = currentVertex + VERTS_IN_QUAD;
        }
    }
    return arrayLevel;
} // End of nextLevel function

Vector2i LevelManager::getLevelSize(){
    return m_LevelSize;
}
int LevelManager::getCurrentLevel(){
    return m_CurrentLevel;
}

Vector2f LevelManager::getStartPosition(){
    return m_StartPosition;
}

LevelManager.h

#pragma once
#include <SFML/Graphics.hpp>
using namespace sf;
using namespace std;

class LevelManager{
    private:
        Vector2i m_LevelSize;
        Vector2f m_StartPosition;
        int m_CurrentLevel = 0;
        const int NUM_LEVELS = 4;

    public:

        const int TILE_SIZE = 50;
        const int VERTS_IN_QUAD = 4;

        Vector2f getStartPosition();
        int** nextLevel (VertexArray& rVaLevel);
        Vector2i getLevelSize();
        int getCurrentLevel();
    };

LoadLevel.cpp

   #include "engine.h"

void Engine::loadLevel(){
    m_Playing = false;
    // Delete the previously allocated memory
    for (int i = 0; i < m_LM.getLevelSize().y; ++i){
        delete[] m_ArrayLevel[i];
    }
    delete[] m_ArrayLevel;
    // Load the next 2d array with the map for the level
    // And repopulate the vertex array as well

    m_ArrayLevel = m_LM.nextLevel(m_VALevel);

    // Spawn Gracza
    m_Player.spawn(m_LM.getStartPosition(), GRAVITY);

    // Make sure this code isn't run again
    m_NewLevelRequired = false;
}

我在 Geany 中编译:

g++ -std=c++11 -c -g  main.cpp levelmanager.cpp engine.cpp playercharacter.cpp player.cpp input.cpp textureholder.cpp update.cpp loadlevel.cpp detectcollisions.cpp draw.cpp

g++ -std=c++11  main.o  levelmanager.o playercharacter.o player.o input.o draw.o engine.o loadlevel.o detectcollisions.o textureholder.o update.o -o sfml-app  -lsfml-graphics -lsfml-window -lsfml-system

之后我通过“./sfml-app”运行它。我尝试运行 gdb,但它只是产生了更多问题: My terminal after running gdb ./sfml-app

抱歉,如果有什么不清楚的地方(还有我的英语不好)。感谢您的时间和帮助。

【问题讨论】:

  • 你试过编译和运行SFML提供的例子吗?这可能是您的代码中的一些问题(尽管 gdb 应该会捕获它),或者某个地方的某些版本不匹配。
  • 我从sfml-dev.org/tutorials/2.4/start-linux.php 运行程序,它对我有用。游戏在早期版本上运行,但后来我不得不引入 levelmanager.cpp loadlevel.cpp 和 detectcollisions.cpp(并更新了其余文件)。

标签: c++11 sfml


【解决方案1】:

像你一样使用gdb,但在main()处设置一个断点,然后逐步执行你的程序。

现在我怀疑程序失败是因为它试图删除以前从未设置的级别(尝试在Engine::loadLevel()而不是main()上设置断点)。

【讨论】:

  • 我的 main.cpp 看起来像这样:int main(){ Engine engine; engine.run(); return 0; } 我试图在 // 的 loadLevel 中删除部分,但它没有改变任何东西。我尝试运行 gdb,它返回:i67.tinypic.com/2m4ocbo.png 我明白,问题出在 loadLevel.cpp 的第 7 行,即delete[] m_ArrayLevel[i]。我是对的,还是我做错了什么?
  • @Avenlith 只需阅读调试输出:问题在loadlevel.cpp,第 7 行。所以它确实应该是(可能)未初始化值的delete[]。另请注意,gdb 会告诉您可执行文件已过时。您确定您更改了文件并重新编译/重新链接它吗?
【解决方案2】:

@马里奥

好的,所以我正在为 loadLevel 尝试新的东西,而 gdb 处于打开状态,所以这就是它返回有关过时 sfml-app 信息的原因。我最终将代码更改为:

void Engine::loadLevel(){
    m_Playing = false;
    // Delete the previously allocated memory
    if (m_NewLevelRequired){
        for (int i = 0; i < m_LM.getLevelSize().y; ++i){
            delete &m_ArrayLevel[i];
        }
        delete[] m_ArrayLevel;
    }

如您所见,我尝试添加“if”以删除上一个级别,直到最后一个级别完成。我试图改变删除的公式,但总的来说并没有太大帮助。 我再次运行 gdb,可以肯定的是,我正确使用了它: http://i67.tinypic.com/1118kuc.png

内存的分配在LevelManager.cpp中:

int** arrayLevel = new int*[m_LevelSize.y];
    for (int i =0; i < m_LevelSize.y; ++i){
        arrayLevel[i] = new int[m_LevelSize.x];
    }

很抱歉在这里发帖,但评论太长了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    相关资源
    最近更新 更多