Wednesday, December 30, 2020

C++ pointers to 2D arrays

I'm dusting off the cobwebs to remember how to do pointers to arrays in C. I had to search for how to do it in C++ because Google is presently incable of returning useful links for C. In my case, I had a collection of predefined 2D arrays that I wanted to chose from to assign pointers to, but couldn't remember the syntax for assigning the pointers or referencing the values from the pointers. So, some research. This question was complicated by the problem that in C multidimensional arrays are actually just concatenated 1D arrays, and there are a couple of totally bonkers ways of getting around this baked into the language. First, the best hits from my searches:
First off, the primer on multi dimensional arrays: https://www.tutorialspoint.com/cplusplus/cpp_multi_dimensional_arrays.htm
This tutorial on array pointers seems lame at first because it starts with just pointers to 1D arrays which wasn't helping me, then I realized that I have to scroll down farther. Note: Check out the sizeof examples somewhere near the end: https://www.geeksforgeeks.org/pointer-array-array-pointer/
This link covers the exact same material, but somehow it seems less opaque. It was from this that I realized that what I needed was to define a pointer as a 1d array pointer of the same number of columns as the 2d array to get what I wanted. And then somehow it works to use that pointer with 2 indexes.https://www.programiz.com/cpp-programming/pointers-arrays
The wags at StackOverflow helped me learn the trick to finding the size of an array: https://stackoverflow.com/questions/10274162/how-to-find-2d-array-size-in-c
Here is the demo program that I tested out on the mbed simulator that has all of the erroneous ways of using array pointers removed, thanks to the above links:
int testme[3][4] = { /* rows, columns */
 {0, 1, 2, 3} , /* initializers for row indexed by 0 */
 {4, 5, 6, 7} , /* initializers for row indexed by 1 */
 {8, 9, 10, 11}
};

int main() {

 int arr[5] = { 1, 2, 3, 4, 5 };
 int *ptr = arr;

 int *ptr2;
 int (*ptr3)[4];

 ptr2 = &testme[0][0];
 ptr3 = testme;

 printf("%p\n", ptr);
 printf("%d\n", ptr[1]);
 printf("%d\n", *(*(testme + 2)));
 printf("%d\n", *(ptr2 + 5));
 printf("%d\n", *(ptr2 + 1));
 printf("%d\n", ptr3[1][2]);

 printf("array number of rows: %d\n",sizeof(testme)/sizeof(testme[0]));
 printf("array number of columns: %d\n",sizeof(testme[0])/sizeof(int));

 return 0;
}
Result of the above:
0x2e60
2
8
5
1
6
array number of rows: 3
array number of columns: 4