C - Pointer to a matrix
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
andj
short
, you should declare themint
.int
is defined to be the “natural” size for integers on the target platform.
Pantelis Sopasakis
Updated on January 18, 2020Comments
-
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 afloat**
. 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
asprocess(&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 likeprocess2(3,4,&a);
. In this way, we acquire access to the elements of the matrix in 2D.