Version 1:
#include <stdio.h> #define MAX 20 typedef int Values[MAX]; int changeArr(int vals2[]) { vals2[0] = 200; vals2[1] = 100; printf("%d and ", vals2[0]); printf("%d\n", vals2[1]); return 0; } int main (int argc, char *argv[]) { Values vals; changeArr(vals); printf("%d and ", vals[0]); printf("%d\n", vals[1]); return 0; }
Instead of passing a pointer to an array, pass a pointer to the first element of the array.
Version 2:
#include <stdio.h> #define MAX 20 typedef int Values[MAX]; int changeArr(Values *vals2) { (*vals2)[0] = 200; (*vals2)[1] = 100; printf("%d and ", (*vals2)[0]); printf("%d\n", (*vals2)[1]); return 0; } int main (int argc, char *argv[]) { Values vals; changeArr(&vals); printf("%d and ", vals[0]); printf("%d\n", vals[1]); return 0; }
use parentheses to compensate for priority.
The problem in your code is that
*vals2[1]
is *(vals2[1]) , so it splits the pointer into one Values unit after the passed pointer. There is no memory available, so this behavior is undefined. In practice, this is the same as access to
arr[1][0]
for
int arr[2][MAX];
But your vals is only (equivalent) a int arr[1][MAX]; therefore you get access beyond. But if nothing worse, *vals2[1] = 100; in changeArr sets vals[MAX] in main to 100. However, it can overwrite something important.
In int changeArr(Values *vals2) you pass a pointer to an array from MAX int s, respectively, the first such array in the Values array. Then vals2[1] is the second array in this Values array (which does not exist here) and *vals2[1] == vals2[1][0] first int in this second array. You want to change the elements of the first (and only) array in the allocated memory block, so you want to access vals2[0][1] or equivalently (*vals2)[1] .
Picture:
vals2 vals2[1] | | vv |vals[0]|vals[1]|...|vals[MAX-1]|x
in changeArr , the vals2 pointer points to a vals array. Since the pointer is int[MAX] , vals2+1 points to int[MAX] with offset MAX*sizeof(int) bytes after the beginning of vals (which is located just below the end of vals ). vals2[1] , or equivalently *(vals2 + 1) , is an array immediately after vals (which does not exist).
You want to change vals[1] , which is in the vals2[0] array, with an offset of 1*sizeof(int) bytes, so you need vals2[0][1] or equivalent (*vals2)[1] .