简体   繁体   中英

C++ SFML Game - Aborted (core dumped)

I was trying out the code from "Beginning C++ Game Programming" and when I try to run the program, I get "Aborted (core dumped)". I suspect that the problem is with pointers, but I don't know how to deal with it. I won't post all my code here, because it's really long, so if something is missing I will add the rest. Here is my codes:

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;
}

I compile this in Geany with:

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

After this I run it by "./sfml-app". I tried running gdb, but it just created more questions: My terminal after running gdb ./sfml-app

Sorry if something is not clear (and my bad english). Thank you for your time and help.

Use gdb as you did, but set a break point at main() , then step through your program step by step.

Right now my suspicion would be the program failing due to it trying to delete the previous level that's never been set (try setting a break point on Engine::loadLevel() rather than main() ).

@Mario

Okay, so I was trying new things for loadLevel, while gdb was on, so it was the reason it returned the information about the outdated sfml-app. I changed the code finally to this:

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;
    }

As you can see I tried to add the "if" to delete previous level only then, when the last one is completed. I tried to change the formula of deleting, but overall it didn't help much. I run the gdb again, to be sure, that I used it correctly: http://i67.tinypic.com/1118kuc.png

The allocation of the memory is in 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];
    }

Sorry for posting here, but it was too long for a comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM