0

I have a MatrixTypeheader file which has the following definition : http://pastebin.com/DMzf1wGB

//Add Two Matrices and store result into another matrix
void Add(MatrixType otherMatrix, MatrixType& resultMatrix);

The implementation of the method above is as such :

void MatrixType::Add(MatrixType otherMatrix, MatrixType& resultMatrix)
{   
    cout << "Inside Add func!" << endl;
    cout << "other matrix : " << endl;
    otherMatrix.PrintMatrix();

    for (int i = 0; i < numRows; i++) {
        for (int j = 0; j < numCols; j++) {
            resultMatrix.values[i][j] = values[i][j] + otherMatrix.values[i][j];
        }
        cout << "\n";
        resultMatrix.PrintMatrix();
        cout << "\n";
    }
}

Definition of PrintMatrix() :

void MatrixType::PrintMatrix()
{
    //Pre: None
    //Post: Matrix is printed row wise
    for (int i = 0; i < numRows; i++) {
        cout << "[ ";
        for (int j = 0; j < numCols; j++) {
            cout << values[i][j];
        }
        cout << "]";
        cout << "\n";
    }

}

Now in my Main.cpp I have MatrixType array like this : MatrixType matrixStore[10] to store 10 MatrixType objects. The complete code for Main.cpp is here : http://pastebin.com/aj2eEGVS

int rows = matrixStore[index1].getRowSize();
int cols = matrixStore[index1].getColSize();
cout << "The two matrices can be added!" << endl;
cout << "Computing... " << endl;

//Create Result Matrix and a pointer variable to it 
MatrixType pResultMatrix = MatrixType(rows, cols);
matrixStore[resultIndex] = pResultMatrix;

//Invoke Add function
matrixStore[index1].Add(matrixStore[index2], matrixStore[resultIndex]);

Now when in my Add() function I do otherMatrix.PrintMatrix() it prints out the values of the matrix invoking the Add() function. And due to this => either I do not have reference to the matrix object invoking the method or the matrix object being passed as the parameter!

Also whenever I do PrintMatrix() after I have added values (in the next round of Switch Case), I always get junk values.

Any solution/explanation to this ?

TIA

Abhishek Ghosh
  • 2,593
  • 3
  • 27
  • 60
  • What are you trying to do here? Doesn't look right: MatrixType pResultMatrix = MatrixType(rows, cols); matrixStore[resultIndex] = pResultMatrix; – phandinhlan Oct 08 '16 at 09:14
  • Your `Add` member function as shown has no valid reason to be a member of `MatrixType`. – tofro Oct 08 '16 at 09:14
  • @phandinhlan: I am creating a new object of MatrixType with a parameterized constructor and assigning that object to an index in the matrixStore. Sounds ok ? – Abhishek Ghosh Oct 08 '16 at 09:25
  • @tofro: Can you please explain to me why ? I am fairly new to C++! – Abhishek Ghosh Oct 08 '16 at 09:25
  • 1
    @AbhishekGhosh You are operating with `MatrixType` object values, not pointers, check my answer for details – Nikita Oct 08 '16 at 09:26
  • Your `Add` "member" takes **three** arguments, one of them that you don't see is the `this` pointer to the object at hand. Rewrite to `Add (const Matrix & otherMatrix)` and do the addition to `this->values` – tofro Oct 08 '16 at 09:35
  • 1. You didn't create a pointer and an object to point to. 2. matrixStore[resultIndex] also isn't a pointer to point to some object. I know what those 2 lines of code does, but I think it's wrong intention. That's why I'm asking what is the "purpose" you're trying to achieve? – phandinhlan Oct 08 '16 at 09:37
  • Why are you printing the resulting matrix at every row you calculate? – Bob__ Oct 08 '16 at 09:38
  • You need to post a [mcve], not a link to code. – juanchopanza Oct 08 '16 at 09:51
  • I do not know who is downvoting these answers - but it is not me! – Abhishek Ghosh Oct 08 '16 at 17:20

4 Answers4

0

In short, matrixStore stores object values, not pointers (as you expect).

//Create Result Matrix and a pointer variable to it 
MatrixType pResultMatrix = MatrixType(rows, cols);
matrixStore[resultIndex] = pResultMatrix;

Seems you expect to store pointer variable, but it's not true. MatrixType value is stored in matrixStore.

The result of this is incorrect matrixStore filling (code from your link):

MatrixType matrix = MatrixType(rows, cols);
matrixStore[index] = matrix;

cout << "Address of matrixStore[index] : " << &matrixStore[index] << endl;
cout << "Address of new matrix is : " << &matrix << endl;

int value;
for (int i = 0; i < rows; i++) {
    cout << "Row " << i << " : ";
    for (int j = 0; j < cols; j++) {
        cin >> value;
        matrix.StoreItem(value, i, j);
    }
}

All changes to matrix are lost as matrixStore contains old copy of matrix object.

Solution:

The proper declaration of matrixStore to keep pointers is:

MatrixType* matrixStore[10]

In case you would like to operate with MatrixType value objects you need to copy objects into matrixStore all time you've modified them.

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Nikita
  • 6,270
  • 2
  • 24
  • 37
  • Thank you for your response! So, If I have a `MatrixType* matrixStore[10]` , will I store objects into it or references of the matrix objects in it ? – Abhishek Ghosh Oct 08 '16 at 09:28
  • Also can you explain as to why my PrintFunction is spitting out junk values ? Also if I have matrixStore as a array of pointers, how do I achieve this : `matrixStore[index1]` ? Currently I have error at that line of code! – Abhishek Ghosh Oct 08 '16 at 09:30
  • @AbhishekGhosh It's better to allocate memory for each object on heap `MatrixType* m = new MatrixType(rows, cols)` and manually cleanup it when you finish `delete m`. Or even use some [smart pointer](http://en.cppreference.com/w/cpp/header/memory) – Nikita Oct 08 '16 at 09:34
  • @AbhishekGhosh There is a good topic about this problem: ["Why should I use a pointer rather than the object itself?"](http://stackoverflow.com/questions/22146094/why-should-i-use-a-pointer-rather-than-the-object-itself). Please check it. – Nikita Oct 08 '16 at 09:40
  • @Nikita That question what you linked is exactly about that using object on the heap in only suggested if the memory usage would be big or the object is needed out of function's scope. In this example none of these conditions is satisfied so I definitely suggest to keep the solution as it just fix the initialization phase. – Tibor Takács Oct 08 '16 at 11:12
  • @TiborTakács Right, AbhishekGhosh should make a decision about an architecture of the application itself. To do that he needs to know pros and cons of different object storing/passing styles. – Nikita Oct 08 '16 at 11:19
  • @AbhishekGhosh If some of answers are useful please consider upvote/accept it to show it's usefulness to the wider community. – Nikita Oct 08 '16 at 15:11
  • @Nikita: This is not pass by reference right ? I assume it is different from using pointers. When passed by reference `&` should be used right ? – Abhishek Ghosh Oct 08 '16 at 17:44
0

The main problem is not in this part of your code but during the matrix creation/initialization. You are storing objects in the array which can be good (especially I like it because it is created on the stack which is much faster, just be aware to do not create too long array to avoid stack overflow) but you have to consider this overall of your code.

For example in the Main.cpp line 38 you copy the content of matrixobject into the array but after that you modify the matrix object which is different from the object which is in the array! This means that the content of the matrix object in the array has some random values. You should modify directly the object in the array, it does not make any sense to have that temporary one.

For example:

matrixStore[index] = MatrixType(rows, cols);

for (int i = 0; i < rows; i++)
{
    std::cout << "Row " << i << " : ";
    for (int j = 0; j < cols; j++)
    {
        std::cin >> value;
        matrixStore[index].StoreItem(value, i, j);
    }
}

I think after this change the part what you copied here should work because there you are working in the array directly.

Some small suggestions:

  1. Pass MatrixType object always as reference if possible. For example, in Add function also the òtherMatrix can be a const ref, your code will be much efficient because the object copy will be not involved. For example:

    void MatrixType::Add(const MatrixType& otherMatrix, MatrixType& resultMatrix);
    

Here the otherMatrix is an input, the resultMatrix is (can be) an output parameter.

  1. In C++ there is real bool type. Avoid bool isAddComp ... if (isAddComp != 0)code, just use if (isAddComp), this is the C++ way.

  2. I would start to use std::vector instead of common arrays, much more flexible and very useful to learn how can you use it.

  3. Personally I would not use ùsing namespace for std it is short and better to read your code (but maybe this is just my code style).

Tibor Takács
  • 3,535
  • 1
  • 20
  • 23
  • I have looked into vectors - But i think for a task such trivial as this, using vectors is not a good option! Also can you give me a short example of Pass By Reference in this case ? – Abhishek Ghosh Oct 08 '16 at 17:43
  • I would use std::vector also in simple cases because it provides more flexibility if some extension is needed. But I can agree with you in this case. You can find an example of pass by reference in the 1st suggestion of mine after my edit. I hope it is clear. – Tibor Takács Oct 08 '16 at 17:52
0

Looking at the code here: http://pastebin.com/aj2eEGVS It looks like the only reason you're creating a local matrix in all your paths, for example:

MatrixType matrix = MatrixType(rows, cols);

is to assign values to the members numRows and numCols. I see you have a commented out SetSize method. I would assume you don't want to do use it because you think the rows and columns shouldn't change after creation.

In that case, your matrixStore should be created as pointers:

MatrixType* matrixStore[10];

Now instead of doing:

MatrixType matrix = MatrixType(rows, cols);
matrixStore[index] = matrix;

You do this:

matrixStore[index] = new MatrixType(rows, cols);

And just use:

matrixStore[index]->StoreItem(value, i, j);

or whatever you want to do with it.

In the end, you just call:

delete matrixStore[index];

For all matrices you have used "new" on. The best way to do this is to assign them to nullptr in the beginning.

MatrixType* matrixStore[10];
for ( unsigned int i = 0; i < 10; ++i )
{
    matrixStore[i] = nullptr;
}

And in the end:

for ( unsigned int i = 0; i < 10; ++i )
{
    if (nullptr != matrixStore[i])
    {
        delete matrixStore[i];
    }
}
phandinhlan
  • 583
  • 1
  • 5
  • 16
  • So I assume all of this is using pointers right ? And it is different from Pass By Reference right ? Is there someway to achieve this using Pass By Reference ? – Abhishek Ghosh Oct 08 '16 at 17:27
  • Passing parameters by "reference" as opposed to by "value" is a concept that can be done in 2 ways in C++, using pointers or references. – phandinhlan Oct 14 '16 at 21:58
-1

Looking at the code in http://pastebin.com/aj2eEGVS

It seems to me you are not initializing the matrix in matrixStore. You are filling the local variable matrix.

MatrixType matrix = MatrixType(rows, cols); // LOCAL VARIABLE

**matrixStore[index] = matrix;** // you are copying the uninitialized matrix

// ...

int value;
for (int i = 0; i < rows; i++) {
    cout << "Row " << i << " : ";
    for (int j = 0; j < cols; j++) {
        cin >> value;
        matrix.StoreItem(value, i, j); // LOCAL VARIABLE
    }
}
cout << endl;
//Print matrix so the use can see
matrix.PrintMatrix();     // PRINT LOCAL VARIABLE
meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Alexander
  • 44
  • 1