May 22, 2016 at 6:15pm May 22, 2016 at 6:15pm UTC
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 May 22, 2016 at 10:35pm May 22, 2016 at 10:35pm UTC
May 22, 2016 at 8:37pm May 22, 2016 at 8:37pm UTC
Please edit your post and put your code in [ code] tags.
May 23, 2016 at 12:46am May 23, 2016 at 12:46am UTC
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.
May 23, 2016 at 2:09am May 23, 2016 at 2:09am UTC
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 May 23, 2016 at 2:15am May 23, 2016 at 2:15am UTC
May 23, 2016 at 3:03am May 23, 2016 at 3:03am UTC
I don't see how that would cause that problem.
May 23, 2016 at 3:47am May 23, 2016 at 3:47am UTC
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 May 23, 2016 at 3:48am May 23, 2016 at 3:48am UTC
May 23, 2016 at 4:17am May 23, 2016 at 4:17am UTC
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!
May 24, 2016 at 2:16am May 24, 2016 at 2:16am UTC
I'm sorry but I am still lost on how to fix this.
May 24, 2016 at 2:33am May 24, 2016 at 2:33am UTC
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.)
May 24, 2016 at 2:40am May 24, 2016 at 2:40am UTC
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 May 24, 2016 at 2:42am May 24, 2016 at 2:42am UTC
May 24, 2016 at 2:56am May 24, 2016 at 2:56am UTC
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 May 24, 2016 at 2:57am May 24, 2016 at 2:57am UTC
May 24, 2016 at 3:01am May 24, 2016 at 3:01am UTC
Removing the reference gets rid of the warnings however it still crashes
May 24, 2016 at 3:10am May 24, 2016 at 3:10am UTC
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 May 24, 2016 at 3:13am May 24, 2016 at 3:13am UTC
May 24, 2016 at 3:15am May 24, 2016 at 3:15am UTC
AAAAHHHHHH! Thank you so much for putting up with me! It works!!!