0

I am having problems with my constructor in class World.

I created a 2D array with pointers where each entry in the array is of type Organism, hence the line of code:

Organism* grid[20][20];

When I run my program, I only see

hello

and after that, I get a message saying that my program has stopped working. I'm pretty sure it's the line of code

grid[i][j]->symbol = ' ';

that's causing the problem. Just to see what would happen, I changed that line to

grid[i][j];

and didn't get any errors. But, the moment I put ->, I seem to get errors.

Is there a reason why my program stops working after I put ->? Any help would be appreciated.

This is my code:

#include <iostream>

using namespace std;

class Organism
{
public: 
    char symbol;
};

class World
{
public:
    World();

private:
    Organism* grid[20][20];
};


int main()
{
    World world;
    return 0;
}


World::World()
{
    for(int i = 0; i < 20; i++)
        for(int j = 0; j < 20; j++)
        {
            cout << "hello" << endl;
            grid[i][j]->symbol = ' ';
            cout << "here" << endl;
        }
}

2 Answers2

0

You have an array of pointers to Organism.

Pointers can not hold any data other than an address. They can only point to memory (that holds data).

Your array's pointers does not point to anything, thats why you get undefined behaviour when you try to assign data to where the pointers point at.

You need to allocate memory for your array.

Organism grid[20][20]; // Create an array of objects (not pointers).
/* ... */
grid[i][j].symbol = ' ';

Same using dynamic memory:

class World {
public:
    World();
    ~World();                                // Rule of Three.
    World(const World&) = delete;            // Rule of Three.
    World& operator=(const World&) = delete; // Rule of Three.
private:
    Organism** grid;
};

World::World() {
    grid = new Organism*[20]; // Allocate memory to point to.
    for(std::size_t i = 0; i != 20; ++i) {
        grid[i] = new Organism[20]; // Allocate memory to point to.
        for(std::size_t j = 0; j != 20; ++j) {
            cout << "hello" << endl;
            grid[i][j].symbol = ' ';
            cout << "here" << endl;
        }
    }
}

// Destructor needed to deallocate memory (otherwise it will leak).
World::~World()
{
    for (std::size_t i = 0; i != 20; ++i) {
        delete[] grid[i];
    }
    delete[] grid;
}

Now you can see how complicated it gets when using dynamic memory and why it's recommended to prefer to use automatic storage duration (i.e. create objects, not pointers and new/delete).

Even better is to use a container from the standard library for storing your elements as e.g. std::vector.

Related:

Community
  • 1
  • 1
Felix Glas
  • 15,065
  • 7
  • 53
  • 82
0

Change

Organism* grid[20][20];

To

Organism  grid[20][20];

and use

grid[i][j].symbol = '';

instead of

grid[i][j]->symbol = '';

and add a default constructor to Organism

class Organism
{
   Organism();
   ...
}

or make Organism a struct

struct Oranism
{
 ...
}
John Doe
  • 146
  • 4