简体   繁体   中英

How do I pass a pointer to a multidimensional array in C?

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.

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 );

@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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM