Reputation: 101
I have a two dimensional array that works with a function:
bool matrix[rows][cols];
func(rows, cols, matrix);
void func(int rows, int cols, bool matrix[rows][cols]) {
//...
}
However, as soon as I try to have matrix
in the original function modified by:
bool matrix[rows][cols];
func(rows, cols, &matrix);
void func(int rows, int cols, bool *matrix[rows][cols]) {
//...
}
I receive an incompatible pointer type error. I am clueless as to why.
Upvotes: 7
Views: 803
Reputation: 20244
@2501 has already answered your question, but, since you want the modified array to be reflected to the main function, you don't actually need a pointer to the array (which will complicate things more)! Just pass the array directly as you'll get the expected results!
Why, you ask?
Short answer: In C, arrays are passed by reference.
Long answer:
Always keep in mind that when you use the name of an array, it gets converted to a pointer to its first element†. This is commonly referred to as "array decay".
Coming back to your code, The diagram of bool matrix[rows][cols];
would be:
+---------------------+---------------------+---------------------+---------------------+---------------------+
| | | | | |
| matrix[0][0] | matrix[0][1] | matrix[0][2] | ... | matrix[0][cols - 1] |
| | | | | |
+---------------------+---------------------+---------------------+---------------------+---------------------+
| | | | | |
| matrix[1][0] | matrix[1][1] | matrix[1][2] | ... | matrix[1][cols - 1] |
| | | | | |
+---------------------+---------------------+---------------------+---------------------+---------------------+
| | | | | |
| ... | ... | ... | ... | ... |
| | | | | |
+---------------------+---------------------+---------------------+---------------------+---------------------+
| | | | | |
| matrix[rows - 1][0] | matrix[rows - 1][1] | matrix[rows - 1][2] | ... | matrix[rows - 1][cols - 1] |
| | | | | |
+---------------------+---------------------+---------------------+---------------------+---------------------+
From the above diagram, it is clear that the first element of
bool matrix[rows][cols];
is the first subarray matrix[0][0]
to matrix[0][cols - 1]
. So what happens here is that the address of this subarray is being passed to the function. This is of type bool (*)[cols]
. This would mean that
void func(int rows, int cols, bool matrix[rows][cols])
would work the same way as
void func(int rows, int cols, bool (*matrix)[cols])
So, for example, if you wanted to write to the third slot of the second subarray of matrix
, you can use matrix[1][2] = WHATEVER;
and the changes made from the function would also affect to the caller since the address was passed.
†: There are a few exceptions where array "decay" doesn't occur. See Exception to array not decaying into a pointer?
Upvotes: 3
Reputation: 21955
A pointer to a single dimensional array, say int a[10]
may look like below:
int (*ptr)[10]
| |______________array of 10 integers(read type and number together)
|______a pointer to ^
A pointer to a multi dimensional array, say int a[10][10]
may look like below:
int (*ptr)[10][10]
| | |_________________array of 10 integers(read type and number together)
| |______________array of ^
|______a pointer to ^
Warning: Mind the parenthesis.
*matrix[rows][cols])
is different from (*matrix)[rows][cols])
. The difference is pointed out in the answer by @2501.
Upvotes: 0
Reputation: 26647
You can use a ***
for a matrix.
char ***matrix = alloc_matrix(BUFFER_SIZE, BUFFER_SIZE);
char ***alloc_matrix(unsigned rows, unsigned columns) {
char ***matrix = malloc(rows * sizeof(char **));
if (!matrix) abort();
for (unsigned row = 0; row < rows; row++) {
matrix[row] = calloc(columns, sizeof(char *));
if (!matrix[row]) abort();
for (unsigned column = 0; column < columns; column++) {
matrix[row][column] = NULL;
}
}
return matrix;
}
Here is an example where we use malloc
and pointers
to create a matrix.
Upvotes: -3
Reputation: 25752
bool matrix[rows][cols]
is an array of arrays of a type bool
bool* matrix[rows][cols]
is an array of arrays of a type pointer to bool
or simply bool*
.
Thus if you defined your function to take an array of arrays of type bool*
, you need to pass that type:
bool* m[row][col];
func( row , col , m );
If you want to have a pointer to bool matrix[rows][cols]
, then your approach is not correct.
A pointer to matrix has the type: bool (*pmatrix)[rows][cols]
. So define your function with that type and pass the address of the matrix array:
func( rows , cols , &matrix );
Upvotes: 7