Segmentation Fault calling public member function

Hey everyone.

It's my first post here and I would like to apologize in advance for the likelihood of it being of little use to anyone else (I will try and rectify that in future questions).

I've been trying to pick up on C++ just through reading and finally decided to have a STL-free attempt at what should eventually be a simple ASCII Cannon game.

I've defined a class Cannon and a class Map as follows:

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
#include "Map.h"

class Cannon
{
private:
    int posX, posY;
    double angle, velocity;
    
    // Cannon is linked to a particular Map
    Map* pMap;
    
    // draws Cannon onto Map defined at location pMap
    void drawCannon();
    
public:
    // constructor
    Cannon(Map& refmap, int x = 0, int y = 0, double a = 0, double vel = 0) : 
        posX(x), posY(y), angle(a), velocity(vel) { 
            pMap = &refmap;
            drawCannon();
            }
    
    // destructor
    ~Cannon() {}
    
    ...

}; 

void Cannon::drawCannon()
{
    // drawing poles
    for (int i = 0; i != posY; ++i)
        pMap->setChar(posX, i, 'H');  
    
    // drawing Cannon
    pMap->setChar(posX, posY, '@');
}


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
class Map
{
private:
    int width;
    int height;
    char **p2DArray;
    
    void create(const int&, const int&, char);
    
public:  
    // constructor
    Map(const int& w = 50, const int& h = 30, char c = ' ') {
        create(w, h, c);
    }
             
    // destructor
    ~Map() {
        for (int i = 0; i != height; ++i)
            delete[] p2DArray[i];
        
        delete[] p2DArray;
    } 
    
    void fill(char);
    
    // defines a particular character in the array
    // y-axis going up
    void setChar(const int&, const int&, char);
    
    ...
    
    void display();
    
};

void Map::create(const int& w = 50, const int& h = 30, char c = ' ')
{
    width = w;
    height = h;
    
    p2DArray = new char*[h];
    for (int i = 0; i != h; ++i)
        p2DArray[i] = new char[w];
    
    fill(c);
}

// fills map with a character
void Map::fill(char c)
{
    for (int i = 0; i != height; ++i)
    {
        for (int j = 0; j != width; ++j)
            p2DArray[i][j] = c;
    }
}

void Map::setChar(const int& x, const int& y, char c) {
        p2DArray[height-y][x] = c;
    }


// displays the map on the standard output
void Map::display()
{
    for (int i = 0; i != height; ++i)
    {
        for (int j = 0; j != width; ++j)
            std::cout << p2DArray[i][j];
            
        std::cout << std::endl;
    }
}


Segmentation fault happens when I call the Cannon constructor in main() as so:
1
2
Map test_map = Map(75,20,' ');
Cannon can1 = Cannon(test_map, 10, 10)


The Map construction seems to work fine as I can display a Map with no problems. Also, calling test_map.setChar(some int, some int, some char) also works.

Debugging gives me the idea that the problem appears when calling setChar through the Cannon construction sequence.

Anyhow, help would be greatly appreciated. Also, any suggestions regarding general program layout are also very welcome.

Thank you - Sylen
1
2
3
void Map::setChar(const int& x, const int& y, char c) {
        p2DArray[height-y][x] = c;  // <-
    }


Why [height-y] ? Why not just [y]?

if y==0, then you'll be accessing [height], which is out of bounds which is probably why you're segfaulting.

If you want to invert y for whatever reason, you'd want [height-y-1]
I find that it is more intuitive for me to "draw" things onto the array if the origin is at the bottom left, hence the (failed) attempt at inverting it. I completely overlooked that detail.

Thanks Disch, that solved it!
Last edited on
Topic archived. No new replies allowed.