segmentation fault (can solve with initialization list, can't with copy constructor)

92 Views Asked by At

I'm having segmentation fault error in my code:

#include <SFML/Graphics.hpp>

#include "game.hpp"
#include "map.hpp"
#include "button.hpp"


class Game {
private:
   Map map;
   Button play_button;
   Button menu_button;
   std::string state = "menu";
public:
    Game(sf::RenderWindow &window) {
        map.setBlockWidth(window);

        sf::Vector2u window_size = window.getSize();
        int button_width = window_size.x / 4;
        int button_height = window_size.y / 10;

        play_button = Button(sf::Vector2f(button_width, button_height), sf::Vector2f((window_size.x / 2) - (button_width / 2), (window_size.y / 2) - (button_height / 2)), [this]() {state = "game";}, "PLAY");
        menu_button = Button(sf::Vector2f(window_size.x / 10, window_size.y / 20), sf::Vector2f(10, 10), [this]() {state = "menu";}, "MENU");
    }

    ~Game() {}
    
    void update(sf::RenderWindow &window, bool LMB_pressed) {
        if (state == "menu") {
            if (LMB_pressed) {
                play_button.detectOnClick(window);
            }

            renderMenu(window);
        } else if (state == "game") {
            if (LMB_pressed) {
                menu_button.detectOnClick(window);
            }

            map.update(window);
            renderInterface(window);
        }
    }

    void renderMenu(sf::RenderWindow &window) {
        window.draw(play_button);
    }

    void renderInterface(sf::RenderWindow &window) {
        window.draw(menu_button);
    }
};

I can fix this problem by moving code below from constructor to update method, but It's horrible solution.

sf::Vector2u window_size = window.getSize();
        int button_width = window_size.x / 4;
        int button_height = window_size.y / 10;

        play_button = Button(sf::Vector2f(button_width, button_height), sf::Vector2f((window_size.x / 2) - (button_width / 2), (window_size.y / 2) - (button_height / 2)), [this]() {state = "game";}, "PLAY");
        menu_button = Button(sf::Vector2f(window_size.x / 10, window_size.y / 20), sf::Vector2f(10, 10), [this]() {state = "menu";}, "MENU");

The other solution is using initialization list:

Game(sf::RenderWindow &window) : play_button(sf::Vector2f(0, 0), sf::Vector2f(0, 0), [this]() {state = "game";}, "PLAY"),
                                     menu_button(sf::Vector2f(0, 0), sf::Vector2f(0, 0), [this]() {state = "menu";}, "MENU") {
        map.setBlockWidth(window);

        sf::Vector2u window_size = window.getSize();
        int button_width = window_size.x / 4;
        int button_height = window_size.y / 10;

        play_button.setPosition(sf::Vector2f((window_size.x / 2) - (button_width / 2), (window_size.y / 2) - (button_height / 2)));
        play_button.setSize(sf::Vector2f(button_width, button_height));

        menu_button.setPosition(sf::Vector2f(10, 10));
        menu_button.setSize(sf::Vector2f(window_size.x / 10, window_size.y / 20));
    }

The problem with this is I'm required to write additional setXXX methods

Ideally I would like to use copy constructor (I think it might work and be the smartest idea), but I can't make it work with compiler auto generated constructor.

Problem seems to be with creating Button objects as member variable, and then assigning button object created in constructor to that member variable. It looks like after leaving constructor objects are deleted.

0

There are 0 best solutions below