0

I am having problems with dynamically changing matrix values using pointer.

I have these global declarations :

int row, col = 0;
float** matrixP;
float** matrixT;
float** matrixP_;

Then I have a function to take inputs from the user to populate Any Matrix I want :

void TakeInput(float** matrix, float row, float col) {

// Initializing the number of rows for the matrix
matrix = new float*[row];

// Initializing the number of columns in a row for the matrix
for (int index = 0; index < row; ++index)
    matrix[index] = new float[col];

// Populate the matrix with data
for (int rowIndex = 0; rowIndex < row; rowIndex++) {
    for (int colIndex = 0; colIndex < col; colIndex++) {
        cout << "Enter the" << rowIndex + 1 << "*" << colIndex + 1 << "entry";
        cin >> matrix[rowIndex][colIndex];
    }
}

// Showing the matrix data
for (int rowIndex = 0; rowIndex < row; rowIndex++) {
    for (int colIndex = 0; colIndex < col; colIndex++) {
        cout << matrix[rowIndex][colIndex] << "\t";
    }
    cout << endl;
}
}

Then I have the main function where I am taking inputs and just trying to show matrixP :

int main() {
// Take the first point input
cout << "Enter the row and column for your points matrix" << endl;
cout << "Enter the number of rows : "; cin >> row;
cout << "Enter the number of columns : "; cin >> col;

TakeInput(matrixP, row, col);
cout << "=============================================================" << endl;
// =============================================================

for (int rowIndex = 0; rowIndex < row; rowIndex++) {
    for (int colIndex = 0; colIndex < col; colIndex++) {
        cout << matrixP[rowIndex][colIndex] << "\t";
    }
    cout << endl;
}
return 0;
}

Now I am having problem in this part :

for (int rowIndex = 0; rowIndex < row; rowIndex++) {
    for (int colIndex = 0; colIndex < col; colIndex++) {
        cout << matrixP[rowIndex][colIndex] << "\t";
    }
    cout << endl;
}

And I got :

// matrixP is throwing access violation error.

Please need a helping hand here to point me out what i am doing wrong here. Thanks in Advance !

Fahim Uddin
  • 681
  • 2
  • 10
  • 36
  • Simplify, simplify, simplify. And if you can't, [make a wrapper class to hide the nastiness.](https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op) – user4581301 Mar 21 '17 at 06:02
  • [Have a read](http://stackoverflow.com/questions/17259877/1d-or-2d-array-whats-faster). – Pixelchemist Mar 21 '17 at 06:12
  • guys come on, i am not trying to optimize my code here, i am trying to find what i am doing wrong with my messy code. I can use class, i can use many other approaches to simplify my things, but i am here to find out what i am doing wrong here logically. – Fahim Uddin Mar 21 '17 at 06:22
  • I'm not even bothering with optimizing at this point. That's a bonus. My point is it's much easier create, manage, and pass around a `matrix` that contains even a `float **` than it is a naked `float **`. For example, `TakeInput` becomes `matrix TakeInput(int row, int col)`. All of the pointer craziness is packaged in `matrix` where you only need to get it right once. – user4581301 Mar 22 '17 at 03:32

2 Answers2

1

The reason you are getting that error is you are passing the matrix as "pass by value" not pass by "reference", so replace your code with this

void TakeInput(float** &matrix, int row, int col)

also row and col should be integers.

Sahib Yar
  • 1,030
  • 11
  • 29
  • 1
    Slight nag: `int` allows the caller to provide negative numbers, and negative array dimensions are... bad. An unsigned integer like `size_t` would be slightly safer. – user4581301 Mar 22 '17 at 03:57
0

Easy, you pass matrixP to TakeInput by value, i.e. you edit copy of it in TakeInput. Do this instead.

void TakeInput(float*** matrix, float row, float col) {
//use (*matrix) instead
//...
}


TakeInput(&matrixP, row, col);

http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/

Pointers are no different from usual ints on that matter.

EDIT:

void TakeInput(float** &matrix, float row, float col) {

// Initializing the number of rows for the matrix
matrix = new float*[row];

// Initializing the number of columns in a row for the matrix
for (int index = 0; index < row; ++index)
    matrix[index] = new float[col];

// Populate the matrix with data
for (int rowIndex = 0; rowIndex < row; rowIndex++) {
    for (int colIndex = 0; colIndex < col; colIndex++) {
        cout << "Enter the" << rowIndex + 1 << "*" << colIndex + 1 <<         "entry";
        cin >> matrix[rowIndex][colIndex];
    }
}
kzawisto
  • 76
  • 5
  • What does this (float*** ) mean here ? if i do that I am getting errors on accessing the matrixP as in the above with for loops. can you explain it a little bit more here. if i don't do that I am getting error : argument of type "float ***" is incompatible with parameter of type "float **" – Fahim Uddin Mar 21 '17 at 06:01
  • `float***` is a pointer to `float**`. You can pass a value by reference by passing pointers around if you need to change the value inside a function. But what if you need to pass a pointer by reference? Well, one way to do that is pass a pointer to the pointer so you can change the value of the pointer. A slightly better way to do this is with a reference to a `float**`: `float **& matrix`. Among other things this makes it much harder to pass a NULL pointer – user4581301 Mar 21 '17 at 06:05
  • Pointer to pointer to pointer, simple as that. If it is C++ not C then you could change it to the pass-by-reference: `void TakeInput(float** &matrix, float row, float col) {`. Then rest of your code is unchanged. – kzawisto Mar 21 '17 at 06:06
  • Okay I understand that, now how will i initialize it as i was trying to initialize above : `matrix = new float*[row];` – Fahim Uddin Mar 21 '17 at 06:16
  • Almost same thing, just change function declaration from pass-by-value to pass by reference by adding ampersand (&). See my updated answer. – kzawisto Mar 21 '17 at 08:00
  • Besides, generally better practice would be to return this pointer to allocated memory from TakeInput, these "output" arguments are hard to read. Even if you really "need" them, returning a struct could be better solution. And as for in-memory matrices software I've seen (i.e. numpy) doesn't do it like that You can just have single, regular pointer `float *matrix = new float[N*M]`, and just refer to it as matrix[x*N +y]. This is faster when doing computation, because single chunk of memory can be cached at once, and is easier to work with. – kzawisto Mar 21 '17 at 08:06