I've made an example program to illustrate the problem. In test
I allocate memory for foo
to store two integers. Then, I set each of these integers to a value, and then I print them. Pretty simple, except I can only assign values to the integers if I do it inside of main
- it won't work when I do it inside of test
.
This code works:
#include <stdio.h>
#include <stdlib.h>
void test(int **foo) {
*foo = malloc(2 * sizeof(int));
}
int main() {
int *foo;
test(&foo);
foo[0] = 4; // <---
foo[1] = 3; // <---
printf("foo[0]: %d\n", foo[0]);
printf("foo[1]: %d\n", foo[1]);
return 0;
}
Output:
foo[0]: 4
foo[1]: 3
This code doesn't:
#include <stdio.h>
#include <stdlib.h>
void test(int **foo) {
*foo = malloc(2 * sizeof(int)); // 3.
*foo[0] = 4; // 4. <---
*foo[1] = 3; // 5. <---
}
int main() {
int *foo; // 1.
test(&foo); // 2.
printf("foo[0]: %d\n", foo[0]);
printf("foo[1]: %d\n", foo[1]);
return 0;
}
Output:
foo[0]: 4 // This is only 4 because it was already
// 4 from running the previous example
foo[1]: 5308612 // And this is obviously garbage
So, what's going on? This answer has been very helpful (or I thought it was at least), but it doesn't address why the assignments work in main
but not test
.
Here's my understanding of how the code in the second example should be working (I've put footnotes in the code to indicate the lines I'm referring to here):
The program starts at main
. I create the integer point foo
, which is assigned a 4-byte block of memory at (for the sake of simplicity) address 1000
.
I send a reference to foo
to the function test
. So, it is passed 1000
as its parameter.
A block of memory two integers in size (8 bytes) is allocated for foo
.
4
is stored at address 1000
3
is stored at address 1004
So, what am I misunderstanding, and how can I fix the code in the second example so I can do my initialization of foo
in a test
rather than main
?
Thanks!
Precedence!
You need:
(*foo)[0] = 4; // 4. <---
(*foo)[1] = 3; // 5. <---
Without the parentheses, *foo[0]
is *(foo[0])
, which is actually the same as (*foo)[0]
, but
*(foo[1])
goes writing who-knows-where. The *
operator binds less tightly than the []
operator does, so you have to use parentheses.
char *arr[]; // array of pointers to char
char (*arr)[]; // pointer to array of char
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With