Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - Pointer to a matrix

Tags:

c

pointers

matrix

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.

like image 422
Pantelis Sopasakis Avatar asked Jul 19 '26 15:07

Pantelis Sopasakis


2 Answers

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.

like image 130
imreal Avatar answered Jul 21 '26 05:07

imreal


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);
like image 39
A.B. Avatar answered Jul 21 '26 06:07

A.B.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!