Code snippets are us

How does one pass a pointer to a multi dimensional array to a function. Oddly, I have nearly zero experience with these multi dimensional array things..

This is how I -thought- I could do it..
My block of data..

byte  grid[GRID_X/8][GRID_Y];
byte* gridPtr = &grid[0][0];

setGrid(gridPtr,13,12,true);   // Example of a call to set grid()..

And my actual function..

void  setGrid(byte* grid,int x,int y,bool value) {

   int   xIndex;
   byte  xBit;
   
   if (x<0 || x>GRID_X) return;
   if (y<0 || y>GRID_Y) return;
   xIndex = x>>3;
   xBit = x - (xIndex<<3);
   if (value) {
      bitSet(grid[xIndex][y],xBit);   // And here the compiler stops.
   } else {
      bitClear(grid[xIndex][y],xBit);
   }
}

How does one do this and keep the compiler happy?

Many thanks!

-jim lele

Have you tried...

void  setGrid(byte grid[GRID_X/8][GRID_Y],int x,int y,bool value) {

Missed it by one equals...

1 Like

Does that pass it in as a pointer?

How about..

void  setGrid(byte grid[][],int x,int y,bool value) {

Thanks for the "=". This code was whipped together in a hurry.

-jim lee

It's actually a reference. From our perspective there is not much difference. As a parameter to a function the only difference is that my snippet carries more type information.

That is exactly the same as a basic pointer.

I suspect you're leaving out something relevant.

Yup I did. I went back with what you told me and tried a few things. grid[][GRIX_Y] was the ticket. I'm guess ing it passed just the pointer on the stack but the compiler had enough info to put together the matrix at compile time. (Because it worked :slight_smile: )

Thanks!

-jim lee

1 Like

That doesn't work because the compiler has no way of knowing the number of columns in 'grid'. It needs that information to index into the array: xIndex * ncols + y

That works because the compiler now knows the number of columns. Of course, now the function only works for arrays with that many columns.

A more general technique would be to pass the array size in the function call:

void  setGrid(byte *grid, uint16_t nRows, uint16_t nCols, uint16_t row, uint16_t col, byte value);

void setup() {
  const uint16_t numRowsA = 10;
  const uint16_t numColsA = 5;
  byte aGrid[numRowsA][numColsA];

  const uint16_t numRowsB = 4;
  const uint16_t numColsB = 8;
  byte bGrid[numRowsB][numColsB];

  setGrid(&aGrid[0][0], numRowsA, numColsA, 1, 1, 5);
  setGrid(&bGrid[0][0], numRowsB, numColsB, 0, 3, 2);
}

void loop() {
}

void  setGrid(byte *grid, uint16_t nRows, uint16_t nCols, uint16_t row, uint16_t col, byte value) {
  uint16_t index;
  if (row >= nRows) {
    return;
  }
  if (col >= nCols) {
    return;
  }

  index = row * nCols + col;
  *(grid + index) = value;
}

But, all of the above are old-school C language techniques. The proper C++ way would be to use a template function and let the compiler figure it all out. But, this obviously only works with arrays whose size is known at compile time.