0

Here is a matrix template I recently started implementing. It doesn't have many functions since, like I said, I just started it.

Header file:

#ifndef MATRIXX_H
#define MATRIXX_H

#include <iostream>
using namespace std;

template <typename theType> class Matrix
{
public:
Matrix()
{
    rows = columns = 0;
    matrixRoot = new theType *[rows];
    for(int i = 0; i < rows; i++)
    {
        matrixRoot[i] = new theType[columns];
    }

}

Matrix(int rows, int columns) 
{
    matrixRoot = new theType *[rows];
    for(int i = 0; i < rows; i++)
    {
        matrixRoot[i] = new theType[columns];
    }
}

~Matrix()
{
    delete [] *matrixRoot;
    delete [] matrixRoot;
}

int numrows() const
{
    return rows;
}

int numcols() const
{
    return columns;
}

private:
int rows;   
int columns;    
theType **matrixRoot;

};

#endif

The problem arises when I try to run this testing program:

#include "matrixx.h"
#include <iostream>

void TestingMatrix()
{
int r = 5;
int c = 4; 
Matrix<int> a(r, c);

cout << "Number of rows: " << a.numrows() << " Number of columns: " << a.numcols() << endl;
}

int main()
{
TestingMatrix();
}

Should it be correct, I'd expect the output to yield something like:

Number of rows: 5 Number of columns: 4

Instead I get something way off:

Number of rows: 134515193 Number of columns: 2515748

It's interesting to note that the number of columns changes but not the rows each time the program is run.

Obviously I won't be able to get anywhere if I can't even initialize an instance of the matrix correctly, so I'd like to know what it is I'm doing wrong that gives me such erroneous results. Btw, I'm aware that my destructor's also messed up since it causes the program to segfault (lol) but that's a problem I plan on addressing on my own in the future. I'd really just appreciate if someone could explain why I'd get those numbers for row and column and how I can get it to return the correct values.

Thank you. (:

JoeC
  • 133
  • 1
  • 2
  • 7
  • What's the point of that default constructor that does nothing? Also, your other constructor should think about exception safety a bit... – Kerrek SB Sep 05 '11 at 00:17

3 Answers3

2
Matrix<int> a(r, c);  // Invokes constructor with arguments.

You are not initializing the member variables rows and columns present in the two argument constructor. And so getting some garbage values from their getters.

Matrix(int rows, int columns) : rows(rows), columns(columns)
                               // ^^^^^^^^^^^^^^^^^^^^^^^^^ Add this
{
       // ....
}
Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • Wow, somehow I knew I'd feel stupid by how simple the answer was. That was it. Thanks! – JoeC Sep 05 '11 at 00:13
  • @JoeC - Sometimes, it happen. But play safe while using raw pointers( it's destruction). `std::vector` is better to use :) – Mahesh Sep 05 '11 at 00:16
  • Oh I know vectors would definitely make my life simpler but part of the assignment explicitly states I cannot use the vector class. Thanks again. – JoeC Sep 05 '11 at 00:20
  • JoeC: I would seriously consider a one-dimensional internal data buffer. Then you can even make the constructor exception-safe without any extra work. – Kerrek SB Sep 05 '11 at 00:21
  • @JoeC - Good Luck with your assignment. – Mahesh Sep 05 '11 at 00:21
1

You forgot to set the rows and columns member variables in one of your constructors. One way is to use assignment, but the preferred and better way to initialize member variables is to use ctor-initializers like this:

Matrix(int rows, int columns) : rows(rows), columns(columns)  
{ 
    matrixRoot = new theType *[rows]; 
    for(int i = 0; i < rows; i++) 
    { 
        matrixRoot[i] = new theType[columns]; 
    } 
} 

The declaration Matrix<int> a(r, c); calls the two-parameter version of the Matrix constructor. That particular version did not initialize the rows and columns variables.

A good rule of thumb is that if you get totally garbage values, you've forgot to initialize them to a reasonable value somewhere.


That being said, I recommend that you pick up a good introductory C++ book and read through it. The errors you're getting is related to initialization of variables, and that is a very fundamental aspect of the language.

Community
  • 1
  • 1
In silico
  • 51,091
  • 10
  • 150
  • 143
0

Because you are not initializing the rows and columns members of your class in the constructor where you pass in the rows and columns. Therefor they contain garbage from the memory.

Matrix(int rows, int columns) 
{
    this->rows = rows;
    this->columns = columns;
    matrixRoot = new theType *[rows];
    for(int i = 0; i < rows; i++)
    {
        matrixRoot[i] = new theType[columns];
    }
}  
ChrisWue
  • 18,612
  • 4
  • 58
  • 83