Memory leak during dynamic allocation of array of pointers

First post here, I'm completely stuck on this problem so I hope someone can help me out. I've searched extensively and I can't wrap my head around this problem.

My program compiles and runs fine, but I have a memory leak that is happening during dynamic memory allocation of an array of pointers-to-objects. I wasn't even aware I had a problem until I ran the debugger in Visual Studio. I will admit this is for a class, but the assignment has already been turned in and the feedback I received said there is a memory leak during allocation.

I've posted what I think the relevant code snippets are below. I'm creating a dynamic array of dynamically created objects. A board is created and filled with dynamically created Animal objects from an Animal class. I don't know if my problem is with my destructor or if I am creating my array incorrectly. Let me know if you have any suggestions or need more code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Board.h

class Board
{
private:

Animal ***arr;
	int numRows;
	int numCols;
	int moves;

public:
Board(int rows, int cols, int numMoves);
~Board();
int getRows();
int getCols();
void fill(int rows, int cols, int crits);
void print();
void placeAnimal();
void placeBorder();
void start();
void sleep(int milliseconds);



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
Board.cpp

Board::Board(int rows, int cols, int numMoves)
{
	moves = numMoves;
	numRows = rows;
	numCols = cols;
arr = new Animal**[rows];
	for (int i = 0; i < rows; i++)
	{
        arr[i] = new Animal*[cols];
		for (int x = 0; x < cols; x++)
		{
			arr[i][x] = NULL;
		}
	}
}

void Board::fill(int rows, int cols, int animals)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			arr[i][j] = new Animal;
			arr[i][j]->setBlank();
		}
	}
	for (int i = 0; i < animals; i++)
	{
		placeAnimal();
	}
	placeBorder();
	
}

void Grid::placeAnimal()
{
	bool NotFree = true;
	while (NotFree == true)
	{
		int x = rand() % (numRows - 2) + 1;
		int y = rand() % (numCols - 2) + 1;
		if (arr[x][y]->getCharType() == ' ')
		{
			arr[x][y] = new Animal;
			arr[x][y]->setAnimal(x, y);
			NotFree = false;
		}
		else
		{
			int x = rand() % (numRows - 2) + 1;
			int y = rand() % (numCols - 2) + 1;
			if (arr[x][y]->getCharType() == 'C')
				NotFree = true;
		}
	}
}

Board::~Board()
{
	for (int i = 0; i < numRows; i++) {
		delete arr[i];
	}
		
		delete[] arr;
		cout << "deleting board..." << endl;
	}



Last edited on
closed account (D80DSL3A)
I do see a couple of problems.
In the fill() function every pointer in the 2d array has an Animal allocated to it (line 25).
On line 31, a number of these animals are placed via call to placeAnimal().
Line 46: arr[i][j] is overwritten with a new Animal*, and the Animal allocated to arr[i][j] in fill() is lost.
The previously allocated Animal should be deleted first:
1
2
delete arr[x][y];// destroy existing
arr[x][y] = new Animal;// create new 

Why destroy and allocate new? There is no change in types pointed to. Animal before and after. Why not just call arr[x][y]->setAnimal(x, y); on the existing instance?
destroy and renew is useful when changing polymorphic types, like if Dog and Cat are derived from Animal:
1
2
3
4
5
Animal* pA = new Cat;// pA points to a Cat
pA->speak();// output = meow
delete pA;// destroy the cat
pA = new Dog;// now pointing to a Dog
pA->speak();// output = woof 


Another problem is in ~Board(). No Animals are deleted, only the pointers!
Reverse the construction.
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
// construction
arr = new Animal**[rows];
for (int i = 0; i < rows; i++)
{
        arr[i] = new Animal*[cols];
	for (int x = 0; x < cols; x++)
	{
		arr[i][x] = new Animal;
	}
}

// destruction
Board::~Board()
{

for (int i = 0; i < numRows; i++)
{
	for (int x = 0; x < numCols; x++)
	{
		delete arr[i][x];// each Animal
	}
        delete [] arr[i];
}
delete [] arr;

}


Lastly, why pass rows, cols to the fill() function? Every array element is to be allocated to, so must have rows = numRows and cols = numCols.
ie.
1
2
3
4
5
void Board::fill(int animals)
{
	for (int i = 0; i < numRows; i++)
	{
		for (int j = 0; j < numCols; j++)
Last edited on
*edit*

Nevermind, your suggestions worked! Thank you so much. My problem stemmed from all the duplicate Animal objects I was creating. Using my Set functions to set them as Blank, Border, or Animal instead of creating whole new objects resolved my problem.
Thanks!
Last edited on
Topic archived. No new replies allowed.