Error with using pointer to a multidimensional array

MyCommon.h (53.8 KB)

I have some multidimensional arrays(Matrix) stored in a header file MyCommon.h (attached above)

I am trying to access these Matrices based on some condition, through a pointer. Below is a simple example without any condition just to make sure the pointer is giving me correct values.

void loop()
{
unsigned long (*pointerArr)[20][2] = UL_ts_2;

Serial.println(pointerArr[0][0][0]);
 Serial.println(pointerArr[1][0][0]);
 Serial.println(pointerArr[2][0][0]);

 delay(1000);
}

-----------------------------------------------------
OUTPUT:
12:47:45.630 -> 18049881
12:47:45.630 -> 6627722
12:47:45.630 -> 8209752
------------------------------------------------------

If i simply do the above then I am able to access all the elements of the matrix UL_ts_2.

Now, when I am trying to add a condition,

int useMAT = 4;
void loop()
{  
  if(useMAT == 2){
    unsigned long (*pointerArr)[20][2] = UL_ts_2;
    }  
  else if(useMAT ==4){
    unsigned long (*pointerArr)[20][4] = UL_ts_4;
    }  
  else if(useMAT ==6){
    unsigned long (*pointerArr)[20][6] = UL_ts_6;
    }
  else if(useMAT ==8){
    unsigned long (*pointerArr)[20][8] = UL_ts_8;
    }
   else{
    unsigned long (*pointerArr)[20][10] = UL_ts_10;
    }
    
  Serial.print("useMAT: ");
  Serial.println(useMAT);

  Serial.println(pointerArr[0][0][0]);
  Serial.println(pointerArr[1][0][0]);
  Serial.println(pointerArr[2][0][0]);

  delay(1000);
}

I am getting the following error

test:214:33: error: invalid types 'long unsigned int[int]' for array subscript
  214 |   Serial.println(pointerArr[0][0][0]);
      |                                 ^
test:215:33: error: invalid types 'long unsigned int[int]' for array subscript
  215 |   Serial.println(pointerArr[1][0][0]);
      |                                 ^
test:216:33: error: invalid types 'long unsigned int[int]' for array subscript
  216 |   Serial.println(pointerArr[2][0][0]);
      |                                 ^
exit status 1
invalid types 'long unsigned int[int]' for array subscript

Can someone please help me with this, I am trying to understand the error but nothing so far.
Any help is appreciated. Thank you

IMO that's a NOP because pointerArr is defined only inside the braces.

@DrDiettrich I see, you are right.

If you understand what I am trying to do here, Do you have any suggestions on how I can use a pointer to point to what matrix I should use based on the value of useMAT?

This may be close to what you try to do:

size_t const useMAT = 4;

void loop() {  
  unsigned long (*pointerArr)[20][useMAT];

  if (useMAT == 2) {
    pointerArr = UL_ts_2;
  }
  // Etc.
    
  Serial.print("useMAT: ");
  Serial.println(useMAT);

  Serial.println(pointerArr[0][0][0]);
  Serial.println(pointerArr[1][0][0]);
  Serial.println(pointerArr[2][0][0]);

  delay(1000);
}

@jfjlaros I did like you suggested,

size_t const useMAT = 4;
void loop()
{
  unsigned long (*pointerArr)[20][useMAT];
//  unsigned long (*pointerArr)[20][2] = UL_ts_2;
  
  if(useMAT == 2){
    pointerArr = UL_ts_2;
    }  
  else if(useMAT ==4){
    pointerArr = UL_ts_4;
    }  
  else if(useMAT ==6){
    pointerArr = UL_ts_6;
    }
  else if(useMAT ==8){
    pointerArr = UL_ts_8;
    }
   else{
    pointerArr = UL_ts_10;
    }
    
  Serial.print("useMAT: ");
  Serial.println(useMAT);

  Serial.println(pointerArr[0][0][0]);
  Serial.println(pointerArr[1][0][0]);
  Serial.println(pointerArr[2][0][0]);

  Serial.println(int(node - '0')-16);

  delay(1000);

}

But it is giving the following error

test:195:18: error: cannot convert 'long unsigned int [10][20][2]' to 'long unsigned int (*)[20][useMAT]' in assignment
  195 |     pointerArr = UL_ts_2;
      |                  ^~~~~~~
      |                  |
      |                  long unsigned int [10][20][2]
test:198:18: error: cannot convert 'long unsigned int [10][20][4]' to 'long unsigned int (*)[20][useMAT]' in assignment
  198 |     pointerArr = UL_ts_4;
      |                  ^~~~~~~
      |                  |
      |                  long unsigned int [10][20][4]
test:201:18: error: cannot convert 'long unsigned int [10][20][6]' to 'long unsigned int (*)[20][useMAT]' in assignment
  201 |     pointerArr = UL_ts_6;
      |                  ^~~~~~~
      |                  |
      |                  long unsigned int [10][20][6]
test:204:18: error: cannot convert 'long unsigned int [10][20][8]' to 'long unsigned int (*)[20][useMAT]' in assignment
  204 |     pointerArr = UL_ts_8;
      |                  ^~~~~~~
      |                  |
      |                  long unsigned int [10][20][8]
test:207:18: error: cannot convert 'long unsigned int [10][20][10]' to 'long unsigned int (*)[20][useMAT]' in assignment
  207 |     pointerArr = UL_ts_10;
      |                  ^~~~~~~~
      |                  |
      |                  long unsigned int [10][20][10]
exit status 1
cannot convert 'long unsigned int [10][20][2]' to 'long unsigned int (*)[20][useMAT]' in assignment

Ah, the compiler did not optimise that away as I expected. I guess I should have checked.

I would go for @DrDiettrich's approach.

You have to provide the array indices.
Also the parentheses in the declaration may be wrong.

Try to understand the mismatching types presented in the error messages.

If you want to assign a long value to pointerArr then pointerArr should be of type long. Please show all the code, where UL_ts... and the array actually are defined.

@DrDiettrich The arrays, UL_ts... are defined inside this header file.

How about posting a small, complete, self-contained example that demonstrates the problem? One that doesn't require that ridiculously large header file?

They are not different types, I have some arrays defined in the header file MyCommon.h and all those arrays are of type unsigned long, the only difference in them is the last dimension.

UL_ts_2 is 10x20x2
UL_ts_4 is 10x20x4
UL_ts_6 is 10x20x6
UL_ts_8 is 10x20x8
UL_ts_10 is 10x20x10

Also, casting seems to be not working, the compiler is not giving any error but the serial monitor is not printing anything except
13:43:02.368 -> useMAT: 4

Arrays of different length are of a different type (even though they contain elements of the same type).

Yes, that was a wrong suggestion of mine. I have deleted that part of my post.

1 Like

Sorry for all the confusion I created. Here is a better example of the problem I am facing and the approach I was taking.
I have 3 unsigned long multidimensional arrays, UL_ts_2(2x20x2), UL_ts_4(2x20x2) and UL_ts_6(2x20x2)
I have a variable, useMAT based on which I have to access the array, if useMAT == 2, then use UL_ts_2 and so on.
Below is the sketch that I had in my mind but I am running into some error.


void setup()
{
  Serial.begin(115200);
  while (!Serial) { // disable this for transmission using battery
    delay(1);
  }
  delay(100);
}


 unsigned long UL_ts_2[][20][2]= 
{ 
{ 
{7183521,15054358},
{3513525,8095206},
{14289139,25676226},
{1438732,25810399},
{12734911,27752201},
{7532396,24679878},
{2375081,11911922},
{6631203,10418229},
{10659272,16612285},
{2870464,27492940},
{11161411,28184787},
{9372707,13017339},
{6841159,19607751},
{9283986,14364804},
{13050979,17856866},
{8380888,29756762},
{14965214,19634068},
{539149,27658707},
{11515074,19730461},
{2405716,10706691}
},
{ 
{5255281,9612658},
{3649293,20408857},
{3909713,7839397},
{1620755,15952189},
{12801070,23459946},
{7888263,21641568},
{3170487,22381978},
{8678940,23113224},
{11832601,26125492},
{21130673,26650729},
{10577002,19285681},
{17484013,29492016},
{11572296,26676557},
{2744130,19929664},
{8170272,16269506},
{19962353,23032229},
{8432494,22504018},
{10968127,17327825},
{4708815,21788327},
{9024753,25027543}
}
}; 
unsigned long UL_ts_4[][20][4]= 
{ 
{ 
{6887281,10431377,14423387,29674734},
{855699,5098194,10242602,23615717},
{4323598,14050633,18232002,24837308},
{2982369,8723629,14223922,24219092},
{1282346,5451338,10084374,14973366},
{5712674,18121455,25252334,29896816},
{1035543,16138287,22178944,25212051},
{3800102,7582790,19654775,24427522},
{1942666,12166996,15289004,25081034},
{2690345,8934233,18047413,29214025},
{10720888,15339088,20359357,24424755},
{286892,3680907,14440622,19757335},
{4714656,13245326,21583348,28553461},
{2276352,14794345,19847612,23185080},
{4585811,7820858,18270903,29470193},
{929590,11070559,21511264,28843956},
{3472109,10359105,21641005,28730096},
{6451108,14675222,18325881,27205782},
{4872556,11708752,23940426,29627903},
{7523500,10620609,17997105,22909985}
},
{ 
{2277384,5849626,12747672,27537002},
{12427873,19583864,23396268,28215977},
{15936,7300593,19855615,27500166},
{1861495,5051385,12380484,16559917},
{2498732,13970187,18269857,21547339},
{257490,8074439,19440059,27705543},
{8595783,12750304,17737653,23715377},
{9408004,15430112,24526746,29522393},
{33062,3817775,19011799,23459314},
{13221256,16602003,22287298,28334250},
{1669342,6866398,18033594,22029610},
{2501358,10429401,14576182,27148973},
{5940817,10792858,23395714,27157834},
{1436617,10737688,14920309,27477426},
{3353771,6904451,25699090,29642159},
{508353,9430217,19479526,27139704},
{3499431,8412216,17947618,28908203},
{1503919,6786951,13933212,18247236},
{3433393,10113238,14835269,18437638},
{3242247,7549632,24961022,28128484}
}
}; 
unsigned long UL_ts_6[][20][6]= 
{ 
{ 
{3584199,9136465,13135067,19773816,25621416,29703935},
{1381758,6033833,11619288,18804660,22389595,28293969},
{2367247,8588529,12836317,17117675,21077918,27199653},
{877638,5513161,9501931,13075653,19263225,26468018},
{615544,5166129,13396518,20100612,23861985,29916158},
{1586096,5264406,8357912,13077912,16087379,26310919},
{1578205,4721599,9105696,16808426,23549719,28291025},
{1986143,9782852,16949818,20185690,23232901,26274562},
{472024,8851744,16977463,20267644,23569043,29946695},
{419760,6598479,12746651,20653097,25489445,29228192},
{1572567,8037902,11722386,16578727,20872337,26419726},
{8686876,13420708,17122344,20875842,26408806,29466540},
{1402967,4534198,10051747,17665808,23340667,29968602},
{2573376,5700811,8780160,15545675,20219416,23578274},
{224071,7305928,10851017,15882044,19362372,28919877},
{925432,6344691,12985969,20906068,24293489,29197976},
{1068664,5160175,10955417,16252120,24023426,28421952},
{1179614,5843778,10725696,18685967,22620575,27818098},
{2269792,7957493,12483714,16687262,25139037,28437653},
{38318,7757025,11224176,17466179,25406833,29230408}
},
{ 
{2508040,6715843,11035756,14174431,18750190,22786456},
{2598405,7692101,13139918,19433181,23891611,29371969},
{2702313,6440898,11071549,20183194,25120749,29364404},
{658615,4465203,7475132,22435346,25793851,28820982},
{1264532,5941628,9282194,15920263,21775578,28353777},
{982084,5248110,8624975,11700015,23231676,27221707},
{23833,4362240,7557470,19199918,23528300,29153991},
{186646,6652909,11086423,20733630,24488609,28102442},
{1314926,6125311,10628668,15478645,22475695,27399227},
{1222408,4613857,12848034,18218949,24566076,29731693},
{849785,5621619,10210910,14857732,17899447,20907680},
{1499914,5668550,8816382,13471028,17359170,23390633},
{171495,3506970,8024148,12050697,21125753,27819109},
{1224563,4396521,8345902,19423314,24143913,27368122},
{2988573,6382336,16968949,20669024,24542018,29219150},
{88424,3574307,13247207,16289786,19985104,24138245},
{1050217,6544856,14524617,20523404,26504647,29640818},
{1038791,8185018,13421103,17327727,22079179,27829221},
{345602,5766500,9062088,12450047,21810047,27889992},
{6737160,10826723,15717352,20259086,23358502,26673468}
}
}; 


size_t const useMAT = 4;

void loop()
{

  if(useMAT == 2){
    unsigned long (*pointerArr)[20][2] = UL_ts_2;
    }
  else if(useMAT ==4){
    unsigned long (*pointerArr)[20][4] = UL_ts_4;
    }  
  else{
    unsigned long (*pointerArr)[20][6] = UL_ts_6;
    }
    
  Serial.print("useMAT: ");
  Serial.println(useMAT);
  Serial.println(pointerArr[0][0][0]);
  Serial.println(pointerArr[1][0][0]);
  Serial.println(pointerArr[2][0][0]);
  delay(1000);

}

-----------------------------------------------------------------------------------------------

ERROR:

test:381:18: error: 'pointerArr' was not declared in this scope
  381 |   Serial.println(pointerArr[0][0][0]);
      |                  ^~~~~~~~~~
exit status 1
'pointerArr' was not declared in this scope

It may help to declare a common base type before adding the last dimension to the arrays. Only that common base type or part of it can be used in a pointer declaration and assignment.

typedef unsigned long baseArray_t[10][20 ];
baseArray_t UL_ts_2[2];
baseArray_t UL_ts_4[4];
...
baseArray_t *pointerArr;

There is no setup() function.

@raghavrathi, you still haven't fixed this problem.

I have added the setup, that's because I was trying to demonstrate the original approach I used.

Just for the record, the following should work, but I still would go for a cleaner solution if possible.

unsigned long UL_ts_2[10][20][2];
unsigned long UL_ts_4[10][20][4];

size_t const useMAT = 2;

void setup() {
  Serial.begin(9600);

  unsigned long (*pointerArr)[20][useMAT];
  
  if (useMAT == 2) {
    pointerArr = reinterpret_cast<unsigned long (*)[20][useMAT]>(UL_ts_2);
  }  
  if (useMAT == 4) {
    pointerArr = reinterpret_cast<unsigned long (*)[20][useMAT]>(UL_ts_4);
  }
  // Etc.

  UL_ts_2[1][2][0] = 1;
  UL_ts_4[1][2][0] = 2;

  // Print "1" if `useMAT` == 2 and "2" if `useMAT` == 4.
  Serial.println(pointerArr[1][2][0]);
}

void loop() {}

[edit]

You can clean this up a little bit by using an additional typedef.

unsigned long UL_ts_2[10][20][2];
unsigned long UL_ts_4[10][20][4];

size_t const useMAT = 2;
typedef unsigned long (*mat_t)[20][useMAT];

void setup() {
  Serial.begin(9600);

  mat_t pointerArr;

  if (useMAT == 2) {
    pointerArr = reinterpret_cast<mat_t>(UL_ts_2);
  }  
  if (useMAT == 4) {
    pointerArr = reinterpret_cast<mat_t>(UL_ts_4);
  }
  // Etc.

  UL_ts_2[1][2][0] = 1;
  UL_ts_4[1][2][0] = 2;

  // Print "1" if `useMAT` == 2 and "2" if `useMAT` == 4.
  Serial.println(pointerArr[1][2][0]);
}

void loop() {}

Note that this is essentially the same as what @johnwasser suggests in post #19, only the syntax for accessing elements is different.

[edit2]

Oh, and also note that I moved the relevant code to setup() only for demonstration purposes.

Here's a method that I think will work.

unsigned long UL_ts_2[10][20][2];
unsigned long UL_ts_4[10][20][4];
unsigned long UL_ts_6[10][20][6];
unsigned long UL_ts_8[10][20][8];
unsigned long UL_ts_10[10][20][10];

void setup()
{
  Serial.begin(115200);
  while (!Serial)   // disable this for transmission using battery
  {
    delay(1);
  }
  delay(100);
}

size_t useMAT = 4;

void loop()
{
  unsigned long *pointerArr = (unsigned long *) &UL_ts_2;

  switch (useMAT)
  {
    case 2: pointerArr = (unsigned long *) &UL_ts_2; break;
    case 4: pointerArr = (unsigned long *) &UL_ts_4; break;
    case 6: pointerArr = (unsigned long *) &UL_ts_6; break;
    case 8: pointerArr = (unsigned long *) &UL_ts_8; break;
    case 10: pointerArr = (unsigned long *) &UL_ts_10; break;
  }

  Serial.print("useMAT: ");
  Serial.println(useMAT);

  Serial.println(pointerArr[(0 * 20) + (0 * useMAT)]);
  Serial.println(pointerArr[(1 * 20) + (0 * useMAT)]);
  Serial.println(pointerArr[(2 * 20) + (0 * useMAT)]);

  delay(1000);
}

Reminds me of This Discussion.

@jfjlaros Thanks for the help, I really appreciate it.