+ 4

Why is the output the same for both &arr and arr in these c code snippets?

Why do Program 1 and Program 2 both output 40? The reason for Program 2 to output 40 is very clear to me but why doesn't the & in Program 1 make a difference? My initial expectation was that Program 1 and Program 3 would behave similarly since both involve calculating the address of an int** instead of an int*. Is there no underlying pointer to the array when malloc or calloc is not used? Program 1: #include <stdio.h> int main() { int arr[3] = {40, 41, 42}; int *ptr = (int*)(&arr); // Notice the &. printf("%d", *(ptr)); return 0; } Program 2: #include <stdio.h> int main() { int arr[3] = {40, 41, 42}; int *ptr = (int*)(arr); // notice the lack of &. printf("%d", *(ptr)); return 0; } // Outputs unpredictable values like 25322080(address of pointer instead of 40) Program 3: #include <stdio.h> #include <stdlib.h> int main() { int *arr = (int*)malloc(3 * sizeof(int)); arr[0] = 40; arr[1] = 41; arr[2] = 42; int *ptr = (int*)(&arr); printf("%d", *(ptr)); free(arr); return 0; }

7th Aug 2021, 1:56 PM
Josh Greig
Josh Greig - avatar
9 Réponses
+ 4
Didn't dive deep into it, but after a test, it shows that in the first program the address of &arr is as same as &arr[0], which make the output more sense since the addresses are the same. However in program 3, they aren't and therefore the output is nonsense. While this difference explained all to me, the reason why the addresses are the same or different is unknown to me.
7th Aug 2021, 2:10 PM
你知道規則,我也是
你知道規則,我也是 - avatar
+ 2
I couldn't quite explain, but for the 3rd snippet I think you probably wanted <ptr> as a pointer to pointer instead. int **ptr = &arr; printf("%d\n\n", *(*ptr)); One doubt here is, do we need to free() <ptr>? since we only use it to point somewhere. If it is necessary, then how to free() <ptr> correctly?
7th Aug 2021, 2:37 PM
Ipang
+ 2
Josh Greig, Not sure how that works. I hope someone more knowledgeable can drop a view here. I didn't say free( arr ); was redundant, it was correct. I was doubting myself what to do in regards to <ptr> being int** (not referring to <arr>), as in do I free() it or not, but I kinda doubt it was necessary.
7th Aug 2021, 3:06 PM
Ipang
+ 1
lpang, I meant to use int* like I did in Program 3 and not int** because that matches the data type conversion from Program 1. Notice the int* and the use of & in Program 1. The point of my question is basically to ask why Program 1 and program 3 behave differently. Why is the memory address different between Program 1 and Program 3 despite the underlying data types being the same and needing to be casted? I'm guessing that since the length of the array is hardcoded to 3 instead of dynamically allocated in Program 1, that means there is no need to save the memory address so arr is just the memory block for the array as apposed to being a pointer variable that has the address of the array's memory block. I just want to see if anyone can confirm or explain it differently. Yes, the free is a bit redundant because it'll be freed upon completing the program. I'm just trying to follow the general rule that every malloc or calloc has a corresponding free.
7th Aug 2021, 2:46 PM
Josh Greig
Josh Greig - avatar