Reputation: 1242
I'm trying to write a function which yields (in the Python generator sense ... roughly speaking) elements of a 2D array one at a time in C. Each of these elements should be a pointer to the 0th value of a 1D subarray. I'm mystified why the code below doesn't work as expected.
#include <stdio.h>
void get_cords(int * coords){
static int count = 0;
int list[][2] = {{0,0}, {1,1}};
// this should assign the starting address of {0,0} to coords the first time the function is called, then the address of {1,1} next time
coords = list[count];
count +=1;
}
void main() {
int coords[] = {0,0};
get_cords(coords);
printf("%d, %d\n", coords[0], coords[1]);
get_cords(coords);
printf("%d, %d\n", coords[0], coords[1]);
}
Output:
0, 0
0, 0
Interestingly, if we assign the values individually in get_coords
, it works as expected:
void get_cords(int * coords){
static int count = 0;
int list[][2] = {{0,0}, {1,1}};
// this should assign the starting address of {0,0} to coords the first time the function is called, then the address of {1,1} next time
coords[0] = list[count][0];
coords[1] = list[count][1];
count +=1;
}
Expected and actual output:
0, 0
1, 1
Can someone explain what is going on here?
Upvotes: 1
Views: 75
Reputation: 6759
You are not passing references here.
Basically this is what is happening:
In you main function, when you do:
This array is not allocated at runtime. Rather it's allocated at compile time. [1]
int coords[] = {0,0};
When you pass this array to function, you are actually passing address of it's first element.
Roughly you can say:
coords —-> &coords[0]
So when you passed coords
to function, you actually passed it's address.
If array was stored at address 1000
, you just passed 1000
. [2]
In the function, int *coords
stored 1000 in it.
Now coords
in the function is some other variable which contains the address to the array.
When you do:
coords = list[count];
You change the address to which coords
points. Now it points to the address of the list
array. This merely changed where the copy that was created when entering the function points.
When you did this:
coords[0] = list[count][0];
coords[1] = list[count][1];
means:
coords[0] —-> *(coords + 0)
coords[1] —-> *(coords + 1)
You changed the values at the address.
Just for a sample which is close to what you were trying to do:
#include <stdio.h>
void get_cords(int ** coords){
static int count = 0;
// list is allocated in stack and
// would be popped off once func call returns if it's not static
// static would cause it to be allocated at compile time
// and it will stay in memory till the end of the program
static int list[][2] = {{0,0}, {1,1}};
// at the address that you received in arg, store the address of new arr
*coords = list[count];
count += 1;
}
void main() {
int coords_arr[] = {0,0};
int *coords = coords_arr;
// now you are actually passing address of coords pointer
get_cords(&coords);
printf("%d, %d\n", coords[0], coords[1]);
get_cords(&coords);
printf("%d, %d\n", coords[0], coords[1]);
}
[1] What does "Memory allocated at compile time" really mean?
[2] Passing an array as an argument to a function in C
Upvotes: 2