1

Creates 2d array of organism class pointers:

try{
    world = new Organism**[worldSizeX];

    for (int x = 0; x < worldSizeX; x++){
        world[x] = new Organism*[worldSizeY];

        // INITATES world ARRAY
        for (int y = 0; y < worldSizeY; y++){
            world[x][y] = new Organism;
        }
        // !INITATES world ARRAY
    }
}
catch (std::bad_alloc){
    std::cout << "Not enough memory for World size" << worldSizeX << "x" << worldSizeY << std::endl;
    deleteWorld(); // DO I NEED THIS?
    init((int)worldSizeX/2, (int)worldSizeY/2, ants, beetles);
    return;
}

if I have bad_alloc I want to call init with smaller int values. Do I have to delete failed array or can I just run it over? And if yes, then how I can delete it, I cant loop through whole array application just crashes.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
Cirvis
  • 382
  • 1
  • 4
  • 15

2 Answers2

3

The reason your program crashes when you try to deleteWorld is because your arrays are not completely initialized. Therefore, you may be encountering uninitialized pointers during this process.

To avoid this, zero-initialize your arrays:

world = new Organism**[worldSizeX]();

(note the trailing (), which signifies zero-initialization of the array).

Now, when you implement deleteWorld, you will have to skip over any entries that are NULL.

Finally: Yes, you do have to delete everything when you get bad_alloc: some objects may already be allocated, and so if you allocated without first deallocating, then you will have a memory leak.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • Since `delete NULL` is legal you shouldn't need to skip over zero pointers. You can just delete them. – Zan Lynx Dec 21 '14 at 11:15
  • @ZanLynx: except that the array elements are pointers to arrays, so by "skip over" I mean "don't iterate inside a NULL pointer". – nneonneo Dec 21 '14 at 11:18
2

if you use vector then the destructor will be called automatically so you won't need it and your program won't leak

try{
    vector< vector < Organism > >world;
    world.resize(worldSizeX);

    for (int x = 0; x < worldSizeX; x++){
        world[x] = vector<Organism>(worldSizeY);//this calls the default constructor so you don't need the second for loop
    }
}
catch (std::bad_alloc){
    std::cout << "Not enough memory for World size" << worldSizeX << "x" << worldSizeY << std::endl;
    init((int)worldSizeX/2, (int)worldSizeY/2, ants, beetles);
    return;
}
Gabriel
  • 3,564
  • 1
  • 27
  • 49
  • and if its just Organism ***world; ? – Cirvis Dec 21 '14 at 11:05
  • `world.reserve(worldSizeX);` should be `world.resize(worldSizeX);` – sgarizvi Dec 21 '14 at 11:09
  • posted the code, tell me if you face problems. In general in C++ don't use new, use vector. It is simpler and you don't have to deal with memory management problems. – Gabriel Dec 21 '14 at 11:09
  • it does not change anything as reserve is the same as resize if the initial size is less than the desired size. But I can change it for people to understand it. – Gabriel Dec 21 '14 at 11:11
  • 1
    You should be able to just skip the last for loop. The vector will default construct each Organism. Now, if this was a `Organism*` vector then it would need a loop doing `world[x][y] = new Organism` but that isn't the case in the answer. – Zan Lynx Dec 21 '14 at 11:16
  • Its is the case world is Organism ***world; :) But thank you so much. – Cirvis Dec 21 '14 at 11:18
  • Program crashes when error is catched and printing out message. – Cirvis Dec 21 '14 at 11:33
  • let me try it when I am back I will fix that – Gabriel Dec 21 '14 at 11:59
  • tried it removing the init function (no definition provided) and it runs smoothly worldSizeX=100, worldSizeY=100. Could you prodived the code that fails? – Gabriel Dec 21 '14 at 20:24