Big array, stack/heap overflow?

Hey, I'm a beginner to cpp, just started poking around with it the other day and now I've ran in to a problem that I can't seem to find any info about using google or the search-function in cplusplus forums.

My following code does nothing useful really, it's just for my own learning.

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
#include <iostream>
using namespace std;

const int MAXX = 400, MAXY = 600;

struct inmatrix {
    int iTerrainType;
    int iTile;
    bool isObstacle;
};

class zone {
    int xsize, ysize;
    char cName[16];
    inmatrix *matrix[MAXX][MAXY];
    public:

        char *pName;

        zone();
        ~zone() { delete matrix; };

        char *getname() { return pName; };
        void setname(char *pN) { pName = pN; }
        bool isObstacle(int x, int y) { return matrix[x][y]->isObstacle; }
        void setObstacle(int x, int y, bool b) { matrix[x][y]->isObstacle = b; }
        bool init(int iSizeX, int iSizeY, char *pNewName = '\0');

};

zone::zone() {
    for (int iA = 0; iA < MAXY; iA++)
        for (int iB = 0; iB < MAXX; iB++)
            matrix [iB][iA] = new inmatrix;

    strcpy(cName, "");
    pName = cName;
}

bool zone::init(int iSizeX, int iSizeY, char *pNewName ) {
    xsize = iSizeX;
    ysize = iSizeY;
    if (!xsize || !ysize) return false;
    if (pNewName) pName = pNewName;
    else if (!pName) pName = "noname";
    for (int a = 0; a < ysize; a++)
        for (int b = 0; b < xsize; b++) {
            matrix[b][a]->iTerrainType = 0;
            matrix[b][a]->iTile = 0;
            matrix[b][a]->isObstacle = false;
        }
    cout << "The zone " << &pName << ":" << pName << " was initialized (" << xsize << ", " << ysize << ")\n";
    return true;
}

int main( int argc, char *argv[] ) {

    zone myzone, myzone2, *pZone;


    pZone = &myzone;
    pZone->init(50, 50, "myzone");
    pZone->setObstacle(0, 0, true);

    myzone2.pName = "myzone2\0";
    myzone2.init(100, 50);


    cout << "\nZone: " << pZone->pName << " Pos: 0, 0 isObstacle: " << (pZone->isObstacle(0, 0)?"true":"false") << "\n";
    cout << "Zone: " << pZone->pName << " Pos: 1, 0 isObstacle: " << (pZone->isObstacle(1, 0)?"true":"false") << "\n";



    return 0;
}


This code as it is works. (probably lots of errors tho, so please point out what I can do better if you wish).

The problem is if i increase MAXX &/or MAXY in the first lines of code,
const int MAXX = 400, MAXY = 600;
to say, about 600x600 the program will compile, but I get a runtime-error if I run it.

I don't get much information, it just say The program has stopped working, windows is checking for a solution for this problem. I'm running this program on Win Vista64.

I suspect I'm overflowing the stack? the heap?

-Psnurr
Last edited on
The stack. I would instead of declaring it like this, make the the array dynamically in the constructor based on the size they want (using new) and then deleteing it in the destructor.
Thanks for the reply, but it didn't make me any wiser :(

I thought this code i have in the constructor for zone:

1
2
3
4
5
6
7
zone::zone() {
    for (int iA = 0; iA < MAXY; iA++)
        for (int iB = 0; iB < MAXX; iB++)
            matrix [iB][iA] = new inmatrix;   // <--- here
        // ..
        // ..
}


would make the program not store the array in the stack?


I guess I could have made the array only as big as needed from the init() function, kind of silly not to. But I'm just doing this program for testing/learning; and the problem I need a solution to is how to put this array somewhere where I can make it larger then [600][600] (which is a bit small for a program crash imo).
FYI:
stack is for static variables, e.g. int i = 0;
heap is for dynamic variables, e.g. int* ptr = new int(0);

I think your issue is you newd some variables (in the constructor) but did not delete them in the destructor.

If you can, I would make your matrix an std::vector< std::vector< inmatrix* > > so that you can have a dynamically allocated matrix without have to deal with as much memory management. Just use .resize() (look it up if you aren't familiar with vectors) to set the size.
Hi, and thanks for replying.

heap is for dynamic variables, e.g. int* ptr = new int(0);


Doesn't that mean that my

inmatrix *matrix[MAXX][MAXY];
along with
1
2
3
    for (int iA = 0; iA < MAXY; iA++)
        for (int iB = 0; iB < MAXX; iB++)
            matrix [iB][iA] = new inmatrix;

would put the array in the heap?


also,
I think your issue is you newd some variables (in the constructor) but did not delete them in the destructor.


I tried this in the destructor
1
2
3
    for (int iA = 0; iA < MAXY; iA++)
        for (int iB = 0; iB < MAXX; iB++)
            delete matrix[iB][iA];


instead of simple
delete matrix;
that I had before, and there were no noticeable difference.


If there is no simple way to use big arrays without using vector I will look into vector. But I keep asking about this because I don't want to just exclude one way of doing something without learning why it won't work :)
Okay, I found out what I had done wrong, and how to do it properly myself. Posting it here if anyone else need to know how.

Full source will go at the bottom of this post.

Here's the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class zone {
    int xsize, ysize;
    char cName[16];
    inmatrix **matrix;

    public:

        char *pName;

        zone();
        ~zone();

        char *getname() { return pName; };
        void setname(char *pN) { pName = pN; }
        bool isObstacle(int x, int y) { return matrix[x][y].isObstacle; }
        void setObstacle(int x, int y, bool b) { matrix[x][y].isObstacle = b; }
        bool init(int iSizeX, int iSizeY, char *pNewName = '\0');

};


as you see i changed inmatrix *matrix[MAXX][MAXY] to inmatrix **matrix

then I changed in the constructor to:
1
2
3
4
matrix = new inmatrix *[MAXY];

    for (int i = 0; i < MAXY; i++)
        matrix[i] = new inmatrix[MAXX];


and similar in the destructor, but backwards :)

1
2
3
4
5
6
zone::~zone() {

    for( int i = 0 ; i < MAXY ; i++ )
        delete [] matrix[i];
    delete [] matrix;
}




And as promised: the full source.

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
#include <iostream>
using namespace std;

const int MAXX = 5000, MAXY = 6600;

struct inmatrix {
    int iTerrainType;
    int iTile;
    bool isObstacle;
};

class zone {
    int xsize, ysize;
    char cName[16];
    inmatrix **matrix;

    public:

        char *pName;

        zone();
        ~zone();

        char *getname() { return pName; };
        void setname(char *pN) { pName = pN; }
        bool isObstacle(int x, int y) { return matrix[x][y].isObstacle; }
        void setObstacle(int x, int y, bool b) { matrix[x][y].isObstacle = b; }
        bool init(int iSizeX, int iSizeY, char *pNewName = '\0');

};

zone::zone() {
    matrix = new inmatrix *[MAXY];

    for (int i = 0; i < MAXY; i++)
        matrix[i] = new inmatrix[MAXX];

    strcpy(cName, "");
    pName = cName;
}
zone::~zone() {

    for( int i = 0 ; i < MAXY ; i++ )
        delete [] matrix[i];
    delete [] matrix;
}

bool zone::init(int iSizeX, int iSizeY, char *pNewName ) {
    xsize = iSizeX;
    ysize = iSizeY;
    if (!xsize || !ysize) return false;
    if (pNewName) pName = pNewName;
    else if (!pName) pName = "noname";
    for (int a = 0; a < ysize; a++)
        for (int b = 0; b < xsize; b++) {
            matrix[b][a].iTerrainType = 0;
            matrix[b][a].iTile = 0;
            matrix[b][a].isObstacle = false;
        }
    cout << "The zone " << &pName << ":" << pName << " was initialized (" << xsize << ", " << ysize << ")\n";
    return true;
}

int main( int argc, char *argv[] ) {

    zone myzone, myzone2, *pZone;


    pZone = &myzone;
    pZone->init(50, 50, "myzone");
    pZone->setObstacle(0, 0, true);

    myzone2.pName = "myzone2\0";
    myzone2.init(100, 50);


    cout << "\nZone: " << pZone->pName << " Pos: 0, 0 isObstacle: " << (pZone->isObstacle(0, 0)?"true":"false") << "\n";
    cout << "Zone: " << pZone->pName << " Pos: 1, 0 isObstacle: " << (pZone->isObstacle(1, 0)?"true":"false") << "\n";

    return 0;
}
Topic archived. No new replies allowed.