Dynamic 2D array with classes; program crashes after destructor

matrixData is a 2D array and is a member variable of the class matrixtype. It is a pointer to a pointer.

I saw in debugging mode that my program crashes after the destructor runs. It seems like after row equals numRows, for some reason row is set back to 0 and it tries to deallocate memory that's already been deallocated.

Does anyone know why this is happening?

1
2
3
4
5
6
7
matrixType::~matrixType()
{
	for (int row = 0; row < numRows; row++)
		delete matrixData[row];

	delete [] matrixData;
}
Are rws itself arrays? If so you should call delete[] matrixData[row];
No, row is just an integer variable used for my for loop to iterate through all the rows of the matrix. But i tried your suggestion and it still doesn't work.
Last edited on
I meant matrixData[row]; elements.

Did you try to use a debugger here? Can you make minimum reproducible example (small code snipped with everything unneeded cut out, which compiles and shows problem)
So I know this code is a bit long for a post but it's short compared to the full thing. I narrowed it down to the bare minimum for the class definition, the main function, and the function definitions.

It should have you input values for a matrix, then print the same matrix you just inputted to the screen. After it does that, when the object goes out of scope and the destructor is called, the program crashes.

Thanks in advance for your help!

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
82
83
84
85
#include <iostream> 

using namespace std;

class matrixType
{
	friend ostream& operator<<(ostream&, const matrixType);

public:
	matrixType();
	~matrixType();
	void setMatrixSize(int row, int col);
	void allocateMatrix();
	void fillMatrix();

protected:
	int numRows;
	int numColumns;
	int **matrixData;
};

int main()
{
	matrixType myMatrix;

	myMatrix.setMatrixSize(3, 4);

	myMatrix.fillMatrix();
	cout << endl << myMatrix;

	return 0;
}

ostream& operator<<(ostream& osObj, const matrixType matrixOutput)
{
	for (int row = 0; row < matrixOutput.numRows; row++)
	{
		for (int column = 0; column < matrixOutput.numColumns; column++)
			osObj << matrixOutput.matrixData[row][column] << " ";
		osObj << endl;
	}

	return osObj;
}

matrixType::matrixType()
{
	numRows = 0;
	numColumns = 0;
	matrixData = 0;
}

matrixType::~matrixType()
{
	for (int row = 0; row < numRows; row++)
		delete matrixData[row];

	delete[] matrixData;
}

void matrixType::setMatrixSize(int row, int col)
{
	numRows = row;
	numColumns = col;
}

void matrixType::allocateMatrix()
{
	matrixData = new int*[numRows];

	for (int row = 0; row < numRows; row++)
		matrixData[row] = new int[numColumns];
}

void matrixType::fillMatrix()
{
	allocateMatrix();

	cout << "Enter values for the " << numRows << "x" << numColumns << " matrix:\n";
	for (int row = 0; row < numRows; row++)
	{
		for (int column = 0; column < numColumns; column++)
			cin >> matrixData[row][column];
	}
}
The problem lies in your operator<< and lack of well-defined copy constructor.

Your operator<< takes right hand argument by value instead of const reference. So copy constructor is called. As you did not define your own, default generated one is used. It just copies pointer values making original and copy to share data.
When lifetime of the copy is coming to an end, destructor is called deleting all data (which is also shared by original). Then original lifetime ends too and its destructor tries to delete already deleted data.
(also you do need to use array delete on line 56 as you used array new on line 72)

Remember Rule of Three: if you need to define one of the following: copy constructor, assigment operator or destructor, you almost always need to define other two.
C++11 add move constructor and move assigment making it Rule of Five.
Thanks! I fixed operator<<. I actually had an overloaded operator= and a copy constructor but I didn't include it in the posted code... probably should have. But my overloaded assignment operator was done incorrectly. I was forgetting to deallocate and reallocate the memory of the left operand, and was simply assigning data values.

By the way, I'm new on this site. How do I mark you as the one that fixed my issue? I want to make sure you get your proper credit, because you've been a lot of help!
Topic archived. No new replies allowed.