Home > Software design >  Passing a multidimensional array as an argument in C
Passing a multidimensional array as an argument in C

Time:12-03

I am trying to initialize matrices in a helper function, but I am getting a warning accessing the matrix inside the helper function that I can't figure out how to fix. I was reading about multidimensional arrays and even saw the same notation used to pass and access a matrix in multiple examples, but mine generates a warning and I'm not quite sure why.

To my knowledge this error means that the argument is not of a type the function is expecting, but I was using it just fine inside the main function before relocating the initialization into its own function. This leads me to think that I'm doing something wrong when passing the matrix to the helper function.

passing argument 1 of 'memmove' makes pointer from integer without a cast [-Wint-conversion] 

Here's my code for the initializer. p is a pointer to data inside an array that I want to initialize into my matrix. I'm using this type of nested for loop to spread 16 bytes of data coming from p into my matrix 1 byte per cell.

void initialize(const unsigned char *p, unsigned char (*matrix)[4]) {

   for (unsigned int i = 0; i < 4; i  ){
       for (unsigned int j = 0; j < 4; j  ){
           memmove(matrix[i][j], p   (4*i j), 1);    <--- Warning here
       };
   };
};

Initialize is being called in another function like this:

void func(const unsigned char *p) {
    unsigned char matrix[4][4] = {
        {0x0,0x0,0x0,0x0},
        {0x0,0x0,0x0,0x0},
        {0x0,0x0,0x0,0x0},
        {0x0,0x0,0x0,0x0}
    };
    initialize(p, matrix);
};

CodePudding user response:

Function memmove() takes a pointer as the first argument. While matrix[i][j] is a char, a type from integer family. Assingning an integer other than constant 0 to a pointer require a cast. Otherwise a warning is raised.

Therefore I expect that in order to copy a single char you should pass a pointer to element matrix[i][j]. Pointers are formed by applying & operator to objects.

memmove(&matrix[i][j], p   (4*i j), 1);

however it can written far simpler, more readable and likely more optimal as:

matrix[i][j] = p[4 * i   j];

or even by copying the whole array without any loops:

memmove(matrix, p, 16);

CodePudding user response:

passing argument 1 of 'memmove' makes pointer from integer without a cast [-Wint-conversion]

Instead of passing an integer value as the destination:

unsigned char (*matrix)[4]
...
//         v----------v This is an integer of type unsigned char   
// memmove(matrix[i][j], p   (4*i j), 1);

Pass the address of the integer as the destination:

memmove(&matrix[i][j], p   (4*i j), 1);
//      ^-----------^ This is an address

void *memmove(void *s1, const void *s2, size_t n); expects s1 to be an address.


matrix in func() is a matrix, aka "2-D array".

matrix in initialize() is not really a matrix, but a pointer to an array[4] of unsigned char.


Since C99 and selectively afterwards, code can use a variable length array notation.

void initialize(size_t rows, size_t cols, unsigned char (*m)[rows][cols],
    const unsigned char *p) {
  printf("%zu %zu %zu\n", rows, cols, sizeof *m);
  for (size_t r = 0; r < rows; r  ){
    for (size_t c = 0; c < cols; c  ){
      (*m)[r][c] = *p  ;
    }
  }
}


#define ROW 5
#define COL 7
int main(void) {
  unsigned char matrix[ROW][COL];
  unsigned char bytes[sizeof matrix] = "Something abcde fghij klmno pqrst uvwxy z";

  size_t r = sizeof matrix / sizeof matrix[0];
  size_t c = sizeof matrix[0] / sizeof matrix[0][0];
  printf("%zu %zu %zu\n", r, c, sizeof matrix);
  initialize(r, c, &matrix, bytes);
}
  • Related