SFML community forums

Help => General => Topic started by: FellowCoder on January 10, 2020, 06:13:34 am

Title: Segmentation Fault
Post by: FellowCoder on January 10, 2020, 06:13:34 am
So, i am making a 2d "game" on sfml and for the first time it gave me a error called  Segmentation Fault. When i run my code the window just opens and close quickly and the console say this error to me, here is my code:


main.cpp:

#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
#include <fstream>
#include "Player.h"
#include <string>

int main(){
        sf::RenderWindow janela(sf::VideoMode::getDesktopMode() , "titulo", sf::Style::Default);


        Player jogador;

        float tempo = 0.0f;
        sf::Clock clock;

        while(janela.isOpen()){
                tempo = clock.restart().asSeconds();

                sf::Event e;
                while(janela.pollEvent(e)){
                        if(e.type == sf::Event::Closed){
                                janela.close();}


                }


                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
                        jogador.corpo.move(0.1f,0);
                        jogador.walking = true;
                }

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
                        jogador.corpo.move(-0.1f,0);
                        jogador.walking = true;
                }

                jogador.Anim(tempo);

                janela.clear(sf::Color(150, 150, 150));
                janela.draw(jogador.corpo);
                janela.display();

        }







        return 0;
}
 


Player.h:

#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>

class Player{
  public:
    Player();
    ~Player();
    sf::Sprite corpo;
    bool walking;
    std::vector<sf::Texture> texturas;


    void Anim(float tempo);


  private:
    int textura;
    float tempoTotal;
    int i;



};


#endif /* end of include guard:  */
 

Player.cpp

#include "Player.h"
#include <iostream>

Player::Player()
{
  textura = 0;
  corpo.setTexture(texturas[0]);
  corpo.setPosition(100.f, 100.f);
  corpo.setOrigin(250,250);
  corpo.setScale(0.2f,0.2f);

  tempoTotal = 0.0f;

  walking = false;
  texturas.reserve(10);

  for (i=0; i < texturas.size(); i++) {
    texturas[i].loadFromFile("Idle (" + std::to_string(i+1) + ").png");
    texturas[i].setSmooth(true);
  }

}

Player::~Player()
{

}

void Player::Anim(float tempo){
  tempoTotal += tempo;
  if (!walking){
    if(tempoTotal >= 0.1f){
      std::cout<<textura<<std::endl;
      tempoTotal = 0;
      textura ++;
      if(textura == texturas.size()){
        textura = 0; }

      corpo.setTexture(texturas[textura]);

    }
  }
  else{
    if(tempoTotal >= 0.3f){
      walking = false;
    }
  }
}
 

i will be really thankful if someone can help me, i am struggling with this error for a long time...



Sorry for my bad english btw :-[
Title: Re: Segmentation Fault
Post by: eXpl0it3r on January 10, 2020, 12:38:12 pm
Try to run it through a debugger.
The debugger will tell you where it crashes and give you a call stack, from which you can figure out what went wrong. Additionally, you can add break points and inspect variable values before the crash.
Title: Re: Segmentation Fault
Post by: nogoodname on January 10, 2020, 01:23:17 pm
std::vector<sf::Texture> texturas;
 

Putting sf::Texture in an std::vector is going to cause you issues.

Sometimes when you call push_back on an std::vector it causes reallocation, so the elements move to another location. 
If there were some pointers pointing to those elements, those pointers will become invalid. 
You can check this stackoverflow answer on iterator invalidation. (https://stackoverflow.com/a/54004916)

Because of this, I don't think std::vector is a good choice for storing textures, since you'll have pointers to elements. 


However here's the source of your current issue.
corpo.setTexture(texturas[0]);
 

You're indexing out of bounds here.
You're trying to get the first element (remember arrays start at 0), but at this point texturas has no elements.

texturas.reserve(10);
for (i=0; i < texturas.size(); i++) {
    texturas[i].loadFromFile("Idle (" + std::to_string(i+1) + ").png");
    texturas[i].setSmooth(true);
}
 
Here is another example of you indexing out of bounds.
Reserve doesn't do what you think it does. It does not change the size of the vector.
What you want to do is resize.

(Also why is i a member variable? It should really be local since you only use it here.)