C - Pointer to a matrix

42,221

Solution 1

There is no need for the triple pointer since you are already supplying the memory. You would use that if you were to allocate the memory inside de function.

You can't index a 2 dimension matrix without supplying at least the size of 1 dimension. The reason is that the compiler needs to generate code to access the correct offset taking into account both dimensions. In this particular case, I suggest passing a simple pointer and indexing as a 1D array, like this:

void process(float *matrix, int nRows, int nCols){
 short i;
 short j;
 for (i=0 ; i<nRows; i++){
   for (j=0 ; j<nCols ; j++){
     matrix[i * nCols + j] *= -1;
   }
 }
}

You can then call it like this:

process((float*)a,3,4);

This way you manually index your buffer.

Solution 2

You have to change the signature of the function to this:

void process(float (*matrix)[3][4], int nRows, int nCols){

And when calling the function, use this:

process(&a, 3, 4);

Solution 3

If you put the nCols parameter before the matrix parameter, you can pass the two-dimensional matrix and use it in the natural way, without extra * operators or index arithmetic:

void process(int nRows, int nCols, float (*matrix)[nCols])
{
    for (short i = 0 ; i < nRows; i++)
    {
        for (short j = 0; j < nCols; j++)
        {
            matrix[i][j] *= -1;
        }
     }
}

Then you call process like this:

process(3, 4, matrix);

Incidentally:

  • Unless there is special reason for making i and j short, you should declare them int. int is defined to be the “natural” size for integers on the target platform.
Share:
42,221
Pantelis Sopasakis
Author by

Pantelis Sopasakis

Updated on January 18, 2020

Comments

  • Pantelis Sopasakis
    Pantelis Sopasakis over 4 years

    I am trying to pass a matrix to a function by reference. The function will replace every element A[i][j] of the matrix by -A[i][j]. I first create the matrix:

    float a[3][4] =
    {
        {1.0f, 0.0f, 0.0f, 0.0f},
        {0.0f, 1.0f, 0.0f, 0.0f},
        {1.0f, 1.0f, 0.0f, 0.0f},
    };
    

    Then, I obtain the pointer to this matrix:

    float*** pa = &a;
    

    Then, I introduce the following function:

    void process(float ***matrix, int nRows, int nCols){
     short i;
     short j;
     for (i=0 ; i<nRows; i++){
       for (j=0 ; j<nCols ; j++){
         (*matrix)[i][j] *= -1;
       }
     }
    }
    

    which I call as follows:

    process(pa,3,4);
    

    My program fails to execute and returns:

    Segmentation fault: 11
    

    Any ideas?

    Summary of the answers: Some notes based on the questions this question received:

    I. The aforementioned function can be used, provided that a is initialized a bit differently so as to be a float**. In particular:

    int numberOfRows = 3;
    int numberOfColumns = 4;
    float **a = (float **) malloc(sizeof (float *) * numberOfRows);
    for (i = 0; i < numberOfRows; ++i) {
        a[i] = (float *) malloc(sizeof (float) * numberOfColumns);
    }
    

    and then, it is passed to the function process as process(&a, 3,4);.

    II. Alternatively, one may use the function:

    void multi_by_minus(float *matrix, int nRows, int nCols) {
      short i,j;
      for (i = 0; i < nRows; i++) {
          for (j = 0; j < nCols; j++) {
              matrix[i * nCols + j] *= -1;
          }
      }
    }
    

    which treats the matrix as an one-dimensional array. In that case we simply invoke it as multi_by_minus(&a, 3, 4);

    III. Finally, we may use the method:

    void process2(int nRows, int nCols, float (*matrix)[nCols]) {
      short i, j;
      for (i = 0; i < nRows; i++) {
        for (j = 0; j < nCols; j++) {
            matrix[i][j] *= -1;
        }
      }
    }
    

    to which we provide a pointer to a, i.e., we invoke it like process2(3,4,&a);. In this way, we acquire access to the elements of the matrix in 2D.