Dynamically allocated 2D array

Hello,

I am programming this in visual studio proff. 2015 and I seem to be running into a problem. In my program, the Matrix class used to be made of a large 2D array, I wanted the size of the matrix to be chosen so I decided to switch over to a dynamically allocated array of arrays. This worked through my entire program except when calling the overloaded * operator, in Matrix.cpp, I get the error
"Run-Time Check Failure #3 - T".

Any assistance would be greatly appreciated!

Note: This is my first time dynamically allocating an pointer array of pointer arrays.


main.cpp:
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
#include"Matrix.h"


int main()
{
	Matrix matrix1;
	Matrix matrix2;
	int row, col;
	cout << "Please enter the size of the first matrix separating the rows and columns by a space (i.e. row col)." << endl;
	cin >> row >> col;
	matrix1.setRowSize(row);
	matrix1.setColSize(col);
	matrix1.setName("Matrix 1");
	matrix1.inputValues();
	cout << "Please enter the size of the second matrix separating the rows and columns by a space (i.e. row col)." << endl;
	cin >> row >> col;
	matrix2.setRowSize(row);
	matrix2.setColSize(col);
	matrix2.setName("Matrix 2");
	matrix2.inputValues();

	string choice;
	while (choice != "!")
	{
		cout << endl;
		matrix1.print();
		matrix2.print();

		cout << "Enter your choice from the list below: " << endl;
		cout << "1. Multiplication operation" << endl;
		cout << "2. Copy operation" << endl;
		cout << "! to exit" << endl;
		cin >> choice;

		if (choice == "1")
		{
			cout << endl << "1. Multiplication operation" << endl;

			//Matrix matrix3;
			Matrix matrix3(matrix1*matrix2);
			matrix3.setName("Matrix 3");
			cout << "The result of multiplying the two matricies is: " << endl;
			matrix3.print();
		}
		else if (choice == "2")
		{
			cout << "2. Copy operation" << endl;
			matrix2 = matrix1;
		}

	}

	return 0;
}




Matrix.h
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
#ifndef MATRIX_H
#define MATRIX_H

#include<iostream>
#include<string>
#include<iomanip>

using namespace std;

const int MAXROW = 100;
const int MAXCOL = 100;

class Matrix 
{
private:
	string name;
	int rowSize;
	int colSize;
	double **matrix;

public: 
	Matrix(); //Defult constructor
	~Matrix();
	Matrix(const Matrix& original); //copy constructor

	void setRowSize(const int i); //sets the number of rows of the matrix
	void setColSize(const int j); //sets the number of columns of the matrix
	void setName(const string name1); //sets the name of the matrix
	void inputValues(); //This function askes the user to input values of the matrix
	void print(); //prints the matrix

	Matrix& operator=(const Matrix& original);
	Matrix& operator*(const Matrix& original);

};
#endif 



Matrix.cpp
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include"Matrix.h"

Matrix::Matrix()
{
	name = "";
	rowSize = 0;
	colSize = 0;
	matrix = NULL;
}

Matrix::~Matrix()
{
	matrix = NULL;
}

Matrix::Matrix(const Matrix& original)
{
	name = original.name;
	rowSize = original.rowSize;
	colSize = original.colSize;
	for (int i = 0; i < original.rowSize; i++)
	{
		for (int j = 0; j < original.colSize; j++)
		{
			matrix[i][j] = original.matrix[i][j];
		}
	}
}

void Matrix::setRowSize(const int i)
{
	rowSize = i;
}

void Matrix::setColSize(const int j)
{
	colSize = j;
}

void Matrix::setName(const string name1)
{
	name = name1;
}

void Matrix::inputValues() // askes for each value individually
{
	matrix = new double*[rowSize];
	for (int i = 0; i < rowSize; ++i)
		matrix[i] = new double[colSize];

	for (int i = 0; i < rowSize; i++)
	{
		for (int j = 0; j < colSize; j++)
		{
			cout << "Please enter the value at possition " << i << ", " << j << "." << endl;
			cin >> matrix[i][j];
		}
	}
}

void Matrix::print()
{
	cout << name << ":" << endl;

	for (int i = 0; i < rowSize; i++)
	{
		for (int j = 0; j < colSize; j++)
		{
			cout << matrix[i][j] << "  ";
		}
		cout << endl;
	}

}

Matrix& Matrix::operator=(const Matrix& original)
{
	//checking that the matricies are the same size
	if (rowSize != original.rowSize || colSize != original.colSize)
	{
		cout << " Cannot copy matricies!" << endl;
		//returns unchanged matrix
		return *this;
	}

	//copies all values of th Matrix class
	name = original.name;
	rowSize = original.rowSize;
	colSize = original.colSize;
	for (int i = 0; i < original.rowSize; i++)
	{
		for (int j = 0; j < original.colSize; j++)
		{
			matrix[i][j] = original.matrix[i][j];
		}
	}
	return *this;
}

Matrix& Matrix::operator*(const Matrix& original)
{
	Matrix *temp;
	//checks that the matricies can be multiplied
	if (colSize != original.rowSize)
	{
		cout << "Cannot multiply these matricies." << endl;
		return *this;
	}
	//multiplies the matrcies if they are able to be
	else if (rowSize == original.colSize)
	{
		temp->name = (name + "*" + original.name);
		temp->rowSize = original.colSize;
		temp->colSize = rowSize;

		temp->matrix = new double*[temp->rowSize];
		for (int i = 0; i < temp->rowSize; ++i)
			temp->matrix[i] = new double[temp->colSize];

		for (int i = 0; i < rowSize; ++i)
		{
			for (int j = 0; j < original.colSize; ++j)
			{
				temp->matrix[i][j] = 0;
				for (int k = 0; k < colSize; ++k)
				{
					temp->matrix[i][j] = temp->matrix[i][j] + (matrix[i][k] * original.matrix[k][j]);
				}
			}
		}
	}
	return *temp;
}
Last edited on
Please edit your post and put your code in [code] tags.
1
2
Matrix* temp;   // temp points to some arbitrary point in memory.
temp->name = (name + "*" + original.name);  // Some arbitrary point in memory is treated as if it is a valid Matrix object. 
Thank you for the suggestion however I originally did not have temp as a pointer at first, but I then switched it to a pointer to try to figure out the problem and the problem persists.
Then supplying the actual code that is causing the problem is surely recommended.

Edit: Looking over your code, there are quite a few potential problems. For instance:
Matrix m; m.print(); results in undefined behavior.
All copies are shallow. All memory allocated is leaked.
Last edited on
I don't see how that would cause that problem.
I don't see how that would cause that problem.

I left out a couple of things.

Undefined behavior:
1
2
3
4
Matrix m;
m.setRowSize(5);
m.setColSize(5);
m.print();


And.. you still have the code up there you say you're not using.
Last edited on
I am using the pointers. I said I switched to then to see if it would help. I'm lazy and have no need to change it back. I'll try your suggestion in the morning. Thank you!
I'm lazy and have no need to change it back.

Except that what you did with temp is completely wrong, and if you were having problems before, you added another problem.
I'm sorry but I am still lost on how to fix this.
At the very least fix the temp problem and supply the modified code that was causing you problems before you added another one. temp should not be a pointer and certainly not a pointer that is not initialized to anything before it's first use (and it's quite likely you ignored a compiler warning telling you this very thing.)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include"Matrix.h"

Matrix::Matrix()
{
	name = "";
	rowSize = 0;
	colSize = 0;
	matrix = NULL;
}

Matrix::~Matrix()
{
	matrix = NULL;
}

Matrix::Matrix(const Matrix& original)
{
	//copies all values of th Matrix class
	name = original.name;
	rowSize = original.rowSize;
	colSize = original.colSize;
	for (int i = 0; i < original.rowSize; i++)
	{
		for (int j = 0; j < original.colSize; j++)
		{
			matrix[i][j] = original.matrix[i][j];
		}
	}
}


void Matrix::setRowSize(const int i)
{
	rowSize = i;
}

void Matrix::setColSize(const int j)
{
	colSize = j;
}

void Matrix::setName(const string name1)
{
	name = name1;
}

void Matrix::inputValues() // askes for each value individually
{
	matrix = new double*[rowSize];
	for (int i = 0; i < rowSize; ++i)
		matrix[i] = new double[colSize];

	for (int i = 0; i < rowSize; i++)
	{
		for (int j = 0; j < colSize; j++)
		{
			cout << "Please enter the value at possition " << i << ", " << j << "." << endl;
			cin >> matrix[i][j];
		}
	}
}

void Matrix::print()
{
	cout << name << ":" << endl;

	for (int i = 0; i < rowSize; i++)
	{
		for (int j = 0; j < colSize; j++)
		{
			cout << matrix[i][j] << "  ";
		}
		cout << endl;
	}

}

Matrix& Matrix::operator=(const Matrix& original)
{
	//checking that the matricies are the same size
	if (rowSize != original.rowSize && colSize != original.colSize)
	{
		cout << " Cannot copy matricies!" << endl;
		//returns unchanged matrix
		return *this;
	}

	//copies all values of th Matrix class
	name = original.name;
	rowSize = original.rowSize;
	colSize = original.colSize;
	for (int i = 0; i < original.rowSize; i++)
	{
		for (int j = 0; j < original.colSize; j++)
		{
			matrix[i][j] = original.matrix[i][j];
		}
	}
	return *this;
}

Matrix& Matrix::operator*(const Matrix& original)
{
	Matrix temp;

	//checks that the matricies can be multiplied
	if (colSize != original.rowSize)
	{
		cout << "Cannot multiply these matricies." << endl;
		return *this;
	}

	//multiplies the matrcies if they are able to be
	temp.matrix = new double*[original.rowSize];
	for (int i = 0; i < original.rowSize; ++i)
		temp.matrix[i] = new double[rowSize];

	temp.setName("New Matrix");
	temp.setRowSize(original.colSize);
	temp.setColSize(rowSize);

	for (int i = 0; i < rowSize; ++i)
	{
		for (int j = 0; j < original.colSize; ++j)
		{
			temp.matrix[i][j] = 0;
			for (int k = 0; k < colSize; ++k)
			{
				temp.matrix[i][j] += (matrix[i][k] * original.matrix[k][j]);
			}
		}
	}
	return temp;
}


There is no compiler error. Everything works great until the * operator is called.
Last edited on
There is no compiler error.

How 'bout compiler warnings? Any of those?

1>...\matrix.cpp(133): warning C4172: returning address of local variable or temporary: temp


You still have a problem with temp. It's a local variable and you're returning a reference to it.

Typically the multiplication operator would return a Matrix by value.
Last edited on
Removing the reference gets rid of the warnings however it still crashes
Returning by value means you bring the copy constructor into play... and your copy constructor has a serious problem. Perhaps you can look at it and tell me what matrix points to when it is first assigned to dereferenced?

[edit: assigned to => dereferenced. matrix is never assigned to in the copy constructor.]
Last edited on
AAAAHHHHHH! Thank you so much for putting up with me! It works!!!
Topic archived. No new replies allowed.