segfault at method invocation

I don't know whether this is a good forum for posting my question because it depends on SFML library, but the SFML forum is little frequented.
So I post my problem here, at the chance that I made a general mistake independent of SFML.

Segfault is at line 119

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <SFML/Graphics.hpp>
#include <array>
#include <chrono>
#include <thread>
#include <iostream>
#include <cstdlib>
#include <forward_list>

const int ROWS = 10;
const int COLS = 20;
const int CELL_SIZE = 16;

namespace LifeName {
enum Life { Grass = 1, Cow };
}

class Life : public sf::Drawable
{
public:
    int age;
    sf::Sprite sprite;
    sf::Vector2<int> pos;
    LifeName::Life lifeName;
    bool is_spawn;
public:
    Life() : age(0), is_spawn(false)
    { sprite.setColor(sf::Color(0xff,0xff,0xff,0x00));}
    
    virtual void draw( sf::RenderTarget & rt, sf::RenderStates s) const override
    {
        rt.draw( sprite );
    }
    virtual void live() = 0;
    virtual void spawn( std::array<std::array<int,COLS>,ROWS> & world) const = 0;
};


class Grass : public Life
{
public:
    void draw( sf::RenderTarget & rt, sf::RenderStates s) const override
    {
        rt.draw(sprite);
    }
    void live() override
    {
        if( is_spawn == true) is_spawn = false;
        
        if( age ++ > 10)
        {
           is_spawn = true;
        }
    }
    void spawn(std::array<std::array<int,COLS>,ROWS> & world) const override {}
};
class Animal : public Life
{

};


class Game : public sf::NonCopyable
{
    std::array<std::array<Life*,COLS>,ROWS> m_grid;
    std::forward_list<Life*> m_lifeList;
    sf::Vector2<int> m_cellSize;
    sf::RenderWindow & m_window;
    sf::Texture m_grassTexture;

public:   
    Game() : m_cellSize(CELL_SIZE,CELL_SIZE),
        m_window( *new sf::RenderWindow(sf::VideoMode(COLS*CELL_SIZE,
        ROWS*CELL_SIZE),"Test") ) 
    {
        m_grassTexture.loadFromFile("/home/nico/develop/c++/sfml/gol/media/64x16_grass.png");
        for ( int row = 0;  row < m_grid.size(); ++row ) {
            for( int col = 0; col < m_grid[row].size();  ++col)
            {
                if( std::rand()%10 == 0) {
                    Life * grassCell = new Grass;
                    m_grid[col][row] = grassCell;
                    grassCell->pos = std::move(sf::Vector2<int>(col, row));
                    m_lifeList.push_front(grassCell);
                    grassCell->sprite.setPosition( col*CELL_SIZE, row*CELL_SIZE );
                    grassCell->sprite.setTexture( m_grassTexture );
                    grassCell->sprite.setTextureRect(
                        sf::Rect<int>(0 ,0, m_cellSize.x, m_cellSize.y )
                    );
                }
                else {
                    m_grid[col][row] = nullptr;
                }
            }
        }
    }
    ~Game()
    {
        delete &m_window;
        for( Life * life : m_lifeList) delete life;
    }
private:
    void draw()
    {             
        for( auto const life : m_lifeList)
        {
            m_window.draw( * life );
        }
    }
    void update()
    {
        for( Life * life : m_lifeList)
            life->live();
     }
     
public:     
    void run()
    {
        std::cerr << "Mark0\n";  //DEBUG
        while( m_window.isOpen() )    // <- Here I get the segfault
        {
            sf::Event event;
            std::cerr << "Mark1\n";  //DEBUG
            while( m_window.pollEvent(event))
            {
                if( event.type == sf::Event::Closed)
                {
                    m_window.close();
                }
            }
            std::cerr << "Mark2\n"; //DEBUG
            m_window.clear( sf::Color::Black );
            draw();
            std::cerr << "Mark3\n"; //DEBUG
            m_window.display();
            update();
            std::this_thread::sleep_for(std::chrono::seconds(1) );
        }
    }
};

int main()
{
    Game game;
    game.run();
}


It's at core the same as this, where I get no segfault:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow & win = *new sf::RenderWindow(sf::VideoMode(200,100),"Test");
        
    while( win.isOpen())
    {
        sf::Event event;
        while( win.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed )
            {
                win.close();
            }
        }
    }
}
Last edited on
std::array<std::array<Life*,COLS>,ROWS> m_grid;
equivalent to m_grid[ROWS][COLS];

but look at how you are accessing it
1
2
m_grid[col][row] = grassCell;
m_grid[col][row] = nullptr;
that's backwards


apart from that,
1
2
//sf::RenderWindow & win = *new sf::RenderWindow(sf::VideoMode(200,100),"Test");
sf::RenderWindow win(sf::VideoMode(200,100),"Test");
There are a lot of problems. This doesn't even look like C++ (*in my opinion).
Last edited on
ne555's array access issue is potentially your issue and should be fixed first.

But I have to ask, why are you dynamically allocating your sf::RenderWindow? There is no tutorial I know of that suggests doing that.
Topic archived. No new replies allowed.