Debugging My Matrix Class Implementation

In summary, the conversation is about a student who joined a platform for physics help but ended up finding the answer to their question by searching through old threads. They are now seeking help for their Intro to Comp. Sci 2 class where they are supposed to implement a matrix class. The student is struggling with their homework and doesn't have time to ask the professor for help. They share the code provided by the professor and ask for assistance.
  • #1
Jennifu
5
0
Hey all! I'm new here. I actually joined for physics help a couple of days ago, but I found the answer by searching through old threads and didn't have to post a new one. So here's my first post. :smile:

Anyway, so I procrastinated on my homework, and now I'm having trouble with it and no longer have time to ask my professor for help before it's due. I'm only in Intro to Comp. Sci 2, so hopefully there are plenty of people who can help me here!

I'm supposed to implement a matrix class. The professor has given us the class declaration and driver. Mine is compiling, but it's freezing when it executes. On the site where we are supposed to upload and test our code, this is the error message that is being displayed: "bash: line 1: 8948 Segmentation fault ./prog2.exe"

Ok, now here's the code. The professor has provided this driver:

Code:
#include <iostream>
#include <iomanip>
#include "Matrix.h"

using namespace std;

ostream& printMatrix(Matrix m, ostream& out);
void TestFunction1(Matrix, Matrix, Matrix);



int main(void)
{

//check to see if the static variable matrixCount has been created and init

    cout << "matrixCount = " << Matrix::get_matrixCount() << endl;
    cout << "(matrixCount should be zero)\n\n";


//create 3 matrices, check matrixCount, .and print matrix dimension

    Matrix A(2,3),B(2,3),C(3,3);

    A = B;

    cout << "Matrix A\n";
    cout << "\t Rows = " << A.getRows()    << endl;
    cout << "\t Cols = " << A.getColumns() << endl;

    cout << "Matrix B\n";
    cout << "\t Rows = " << B.getRows()    << endl;
    cout << "\t Cols = " << B.getColumns() << endl;

    cout << "Matrix C\n";
    cout << "\t Rows = " << C.getRows()    << endl;
    cout << "\t Cols = " << C.getColumns() << endl;


    cout << endl;
    cout << "matrixCount = " << Matrix::get_matrixCount() << endl;
    cout << "(matrixCount should be three (3))\n\n";

//Test the copy constructor and destructor
    cout << endl;
    cout << "matrixCount = " << Matrix::get_matrixCount() << endl;
    cout << "(before call the TestFunction1)\n\n";

    TestFunction1(A,B,C);

    cout << endl;
    cout << "matrixCount = " << Matrix::get_matrixCount() << endl;
    cout << "(after call the TestFunction1)\n\n";


//create some data arrays

	int row, col, index;
	int data1[]={1,2,3,4,5,6};
	int data2[]={10,20,30,40,50,60};
	int data3[]={-5,-10,-15,0,5,10,15,36,42};



//Fill Matricies A, B will initial values
//Test setElement
	index = 0;
	for(row = 0; row < 2; row++)
	  for(col = 0 ; col < 3; col++)
	  {
	    A.setElement(row, col, data1[index]);
	    B.setElement(row,col,data2[index]);
	    index++;
	  }

//Fill Matricies C will initial values
//Test overloaded []
    index = 0;
	for(row = 0; row < 3; row++)
	  for(col = 0 ; col < 3; col++)
	  {
	    //C.setElement(row, col, data3[index++]);
	    C[row][col] = data3[index++];
	  }


//Print Matricies A, B, C

	cout<<"Matrix A\n\n";
	printMatrix(A,cout);
    cout << endl << endl;

	cout<<"Matrix B\n\n";
	printMatrix(B,cout);
    cout << endl << endl;

	cout<<"Matrix C\n\n";
	printMatrix(C,cout);
    cout << endl << endl;



//Addition

	cout<<"Matrix A + B\n\n";
	printMatrix(A.add(B),cout);
    cout << endl << endl;




//Test Subtraction

	cout<<"Matrix A - B\n\n";
	printMatrix(A.subtract(B),cout);
    cout << endl << endl;




//Test Multiplication

 	cout<<"Matrix A * C\n\n";
	printMatrix(A.multiply(C),cout);
    cout << endl << endl;


	return 0;
}




//Function to print a Matrix

ostream& printMatrix(Matrix m, ostream& out)
{
    int row, col;
    int r,c;

    row = m.getRows();
    col = m.getColumns();

  	for(r = 0; r < row; r++)
	{
	  for(c = 0 ; c < col; c++)
	    out <<setw(4)<< m.getElement(r, c)<<" ";
	  out<<endl;
	}

    return out;
}


//Test Function 1, test copy constructor
void TestFunction1(Matrix x, Matrix y, Matrix z)
{
    cout << endl;
    cout << "matrixCount = " << Matrix::get_matrixCount() << endl;
    cout << "(In TestFunction1)\n\n";


   return;
}

Here is my header file, Matrix.h:
Code:
#ifndef _MATRIX_
#define _MATRIX_

class Matrix
{
    public:
        Matrix(int r=0, int c = 0);
        Matrix(const Matrix& m);
        ~Matrix();
        Matrix operator= (Matrix);
        int* operator[] (int);
        int getRows() const;
        int getColumns() const;
        int getElement(int r, int c) const;
        void setElement (int r, int c, int v);
        Matrix add (const Matrix& m) const;
        Matrix subtract (const Matrix& m) const;
        Matrix multiply (const Matrix& m) const;
        static int get_matrixCount ();
    private:
        int rows, cols;
        int **element;
        static int matrixCount;
};


#endif //_MATRIX_

And here are the functions for the class:
Code:
#include "Matrix.h"

int Matrix::matrixCount = 0;

Matrix::Matrix(int r, int c)
{
    if (r > 0 && c > 0)
    {
        rows = r;
        cols = c;
    }
    else
    {
        rows = 0;
        cols = 0;
    }

    element = new int* [rows];

    for (int i=0; i<rows; i++)
    {
        element[i] = new int[cols];
        for (int n = 0; n<cols; n++)
        {
            element[i][n] = 0;
        }
    }
    matrixCount++;
}

Matrix::Matrix(const Matrix& m)
{
    for (int i=0; i<rows; i++)
    {
        delete []element[i];
    }

    delete []element;

    rows = m.rows;
    cols = m.cols;

    element = new int* [rows];

    for (int i=0; i<rows; i++)
    {
        element[i] = new int[cols];
        for (int n = 0; n<cols; n++)
        {
            element[i][n] = m.element[i][n];
        }
    }

}

Matrix::~Matrix()
{
    for (int i=0; i<rows; i++)
    {
        delete []element[i];
    }

        delete []element;
}


Matrix Matrix::operator=(Matrix m)
{
    for (int i=0; i<rows; i++)
    {
        delete []element[i];
    }

    delete []element;

    rows = m.rows;
    cols = m.cols;

    element = new int* [rows];

    for (int i=0; i<rows; i++)
    {
        element[i] = new int[cols];
        for (int n = 0; n<cols; n++)
        {
            element[i][n] = m.element[i][n];
        }
    }

    return *this;
}

int* Matrix::operator[] (int n)
{
    return element[n];
}

int Matrix::getRows() const
{
    return rows;
}

int Matrix::getColumns() const
{
    return cols;
}

int Matrix::getElement(int r, int c) const
{
    return element[r][c];
}


void Matrix::setElement (int r, int c, int v)
{
    if (r>=0 && r<=rows && c>=0 && c<=cols)
        element[r][c] = v;
}

Matrix Matrix::add (const Matrix& m) const
{

    for (int i=0; i<rows; i++)
    {
        for (int n = 0; n<cols; n++)
        {
            element[i][n] += m.element[i][n];
        }
    }

    return *this;
}

Matrix Matrix::subtract (const Matrix& m) const
{
    for (int i=0; i<rows; i++)
    {
        for (int n = 0; n<cols; n++)
        {
            element[i][n] -= m.element[i][n];
        }
    }

    return *this;
}

Matrix Matrix::multiply (const Matrix& m) const
{
    Matrix product;

    product.rows = rows;
    product.cols = m.cols;

    for (int i=0; i<product.rows; i++)
    {
        for (int n = 0; n<product.cols; n++)
        {
            for (int m=0; m<cols; m++)
            {
                product.element[i][n] += element[m][m];
            }
        }
    }

    return product;
}

int Matrix::get_matrixCount()
{
    return matrixCount;
}

Can anyone figure out what's happening? I'm feeling kind of stupid right now, because I've been trying to figure it out forever. Oh, and if you see anything else I might need to fix, can you tell me that as well? Thanks!
 
Technology news on Phys.org
  • #2
hey Jen, I am not going to have a chance to look at this, but post your specific compiler and version info for the experts who will.
I run into problems all the time just between working in MS Visual C++ 6 and .NET.
 
  • #3
I usually work in Code::Blocks v1.0, but I also tried this on Dev-C++ 4.9.9.2. Also, it doesn't work on the site where I upload it (I have no idea how my professor has programmed that site).
 
  • #4
Your operator= really ought to take a const Matrix& as its argument and return a Matrix&.

That's not the bug you're seeing, but it's triggering one of your bugs too early. Once you make that fix, the driver program will help you find your other bugs. I'll give you a chance to spot them before telling you what they are.

By the way, surely your program gave some output before freezing? That output really helps track down bugs, you should state what output you got when posting errors like this. (In fact, when I'm not using a debugger, I track down bugs by inserting lots and lots of output statements, so I can pin down where the program is failing)
 
Last edited:
  • #5
Oh, and I think there's one extremely pedantic error you've made -- though you will almost never run into real problems because of it... your header guard shouldn't have a leading underscore. _MATRIX_ is (technically) bad: but MATRIX or MATRIX__ or something like that is fine.
 
  • #6
Thanks for you help!

I fixed the things you mentioned, and it's definitely helped. I haven't yet found the other bugs, though.

Anyway, the output I'm getting is this:
matrixCount = 0
(matrixCount should be zero)

Matrix A
Rows = 2
Cols = 3
Matrix B
Rows = 2
Cols = 3
Matrix C
Rows = 3
Cols = 3

matrixCount = 3
(matrixCount should be three (3))matrixCount = 3
(before call the TestFunction1)

So I'm assuming it's something to do with TestFunction 1, because that is where it is freezing. Is it something to do with my copy constructor?
 
  • #7
Yep, your copy constructor is a problem. What is your copy constructor doing? Are all of those things appropriate for an object which does not yet exist?
 
  • #8
OOOOOH! ok, I got it. And I also fixed my addition, subtraction, and multiplication functions, which were wrong. I think it's working now, unless there's something else you saw.

Thank you very much!
 
  • #9
Hurkyl said:
Oh, and I think there's one extremely pedantic error you've made -- though you will almost never run into real problems because of it... your header guard shouldn't have a leading underscore. _MATRIX_ is (technically) bad: but MATRIX or MATRIX__ or something like that is fine.

Why is that a problem?
 
  • #10
Possibly could cause a linking error perhaps?
 
  • #11
Use the debugger whenever you see an error like the one you had (segmentation fault).

In fact, use the debugger, period. The only way to make sure your code is truly doing the right thing is to step the debugger through each line of code. Developers often have to certify that they did so in rigorous software development environments.

Hurkyl said:
By the way, surely your program gave some output before freezing?

Segmentation faults often cause buffered output to disappear. One way around this is to unbuffer standard output and standard error.
 
  • #12
nmtim said:
Why is that a problem?
Any symbol beginning with two underscores, or beginning with an underscore and a capital letter are reserved for the implementation of the C library. So, technically, using _MATRIX_ in that way could run into undefined behavior should the C library decide to do something with that symbol.

(there's a similar problem with a symbol beginning with an underscore and a lower case letter, but it's not as restrictive)

But this is one of those things that will rarely cause a problem -- I just bring it up because it does cause problems occasionally.


D H said:
Use the debugger whenever you see an error like the one you had (segmentation fault).
I agree, a debugger is a really good thing to use.


Segmentation faults often cause buffered output to disappear. One way around this is to unbuffer standard output and standard error.
std::endl is supposed to flush the buffer, so we should have at least seen the first line. Many systems line buffer stdout, so we should have seen the second line too.
 
  • #13
I'm just learning to use the debugger, and unfortunately, I learned it during lab on a different compiler. I tried it for that last assignment, but on both Code::Blocks and Dev C++, it kept saying something like there was no debugging info. I tried to follow the instructions to fix it, but couldn't figure it out. Any tips?

And yeah, when I couldn't get it to work, the first two lines of output were displayed before it froze.
 

What is debugging and why is it important?

Debugging is the process of identifying and fixing errors, or bugs, in computer programs. It is important because it ensures that the program functions correctly and produces the desired results.

How can I debug my matrix class implementation?

There are several methods for debugging a matrix class implementation. One approach is to use print statements to track the values of variables and identify any unexpected values. Another option is to use a debugger tool, which allows you to step through the code and examine the values of variables at each step.

What are some common errors in matrix class implementations?

Some common errors in matrix class implementations include incorrect indexing, incorrect calculations, and missing or extra parentheses. It is also important to check for errors related to memory allocation and deallocation.

How can I prevent bugs in my matrix class implementation?

To prevent bugs in your matrix class implementation, it is important to thoroughly test your code and handle edge cases. It can also be helpful to follow good coding practices, such as using meaningful variable names and commenting your code.

What should I do if I am unable to find and fix a bug in my matrix class implementation?

If you are unable to find and fix a bug in your matrix class implementation, it can be helpful to seek assistance from others, such as colleagues or online communities. It may also be beneficial to take a break and come back to the problem with a fresh perspective.

Similar threads

  • Programming and Computer Science
Replies
5
Views
2K
  • Programming and Computer Science
Replies
23
Views
2K
Replies
10
Views
951
  • Programming and Computer Science
2
Replies
66
Views
4K
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
Replies
22
Views
2K
  • Programming and Computer Science
2
Replies
36
Views
2K
  • Programming and Computer Science
3
Replies
89
Views
4K
  • Programming and Computer Science
Replies
4
Views
1K
Back
Top