0

I would like to know the main differences between a matrix stored "as a multidimensional array" in the stack and a matrix stored "as an array of pointers" in the heap.

In particular can the matrix as "multidimensional array" in the stack still be seen and used as an array of pointers?

I'm having troubles to understand why I cannot do the following: Suppose that I want to set one row of a matrix B equal to an other row of the same matrix, but I don't want to use a loop on the columns index, i.e. I don't want to set the single elements of the matrix equal to each other but move the rows directly.

Here are the three ways I tried

#include <iostream>
using namespace std;

int main() {
    int xsize=3, ysize=3;
    int row1, row2;

    int B[][3]={{1,2,3},{4,5,6},{7,8,9}};

    cout << "Row to change?";
    cin >> row1 ;
    cout << "Which row must it be set equal to?";
    cin >> row2 ;

    //1): set the two rows equal directly:

    B[row1 - 1] = B[row2 - 1];

    //gives error : "invalid array assignment" 

    //------------------------------------------------------------------------

    //2) create copy on the heap and set the row of B equal to the row of matrix

    int ** matrix = new int*[ysize];
    for(int i = 0; i < ysize; i++) {
        matrix[i] = new int[xsize];
    }

    for(int i = 0; i < ysize; i++) {
        for(int j = 0; j < xsize; j++) {
            matrix[i][j]=B[i][j];
        }

      B[row1 - 1] = matrix[row2 - 1];

   //gives the error "incompatible types in assignment of 'int*' to 'int [3]"

    //------------------------------------------------------------------------

   //3) the same as 2) but reversed

     matrix[row1 - 1] = B[row2 - 1];

   //this one works, so that I can print the matrix modified

    for(int i = 0; i < ysize; i++) {
        for(int j = 0; j < xsize; j++) {
            cout << matrix[i][j] << " ";
        }
        cout << "\n";
    }
}

I can't understand why 1) and 2) do not work, while 3) does. What is exaclty the difference if I reverse the equality in 2) (which I did in 3)) and why does it work only in that way?

I thought that a matrix can be seen as an array of pointers anyway, since if I print something like cout << B[1]; gives me the memory index of the first element of second row, which is an array, so B[1] should behave like a pointer to the second row.

Also is there a more correct way to move or copy rows of a matrix (again without using a loop on the columns)?

trincot
  • 317,000
  • 35
  • 244
  • 286
Gianolepo
  • 155
  • 7
  • https://stackoverflow.com/questions/46991224/are-there-any-valid-use-cases-to-use-new-and-delete-raw-pointers-or-c-style-arr – user0042 Dec 02 '17 at 15:56
  • Change your heap-based matrix to [this](https://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in-c/21944048#21944048) instead of what you have now. – PaulMcKenzie Dec 02 '17 at 15:59

1 Answers1

1

One of the quirks of C is that multi-dimensional arrays are hard to work with. Most beginners' books introduce them in the same chapter as 1D arrays, before the reader is ready to understand some of the subtle difficulties.

One of those subtle difficulties is that the syntax

mtx[i][j]

can refer to a 2D array, or it can refer to a double pointer. If it refers to a double pointer, mtx is a type **, and holds a list of pointers to 1D arrays, which are the rows of the matrix. Note that the matrix can be ragged, something that isn't allowed with true 2D arrays in C.

To answer your question, in reality if mtx is a type **, we will construct it on the heap. You can construct it on the stack but only by coding round the type system. A true matrix can be on the heap or on the stack, but the syntax for creating one on the heap is anther of the subtle difficulties of 2D matrices in C.

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18