First, the declaration int *foo
makes foo
a pointer, not an array.
(int[]){1,2,3,4,5}
is a compound literal. It is rare there is a good reason to set pointers to compound literals in this way.
Compound literals are managed automatically, so you do not need to free them. If a compound literal appears outside any function, it has static storage duration; it exists for the entire execution of the program. Otherwise, it has automatic storage duration associated with the block it is in, and its memory reservation will end when execution of that block ends. You should not set a pointer to point to such a compound literal if the pointer is used after execution of the block ends.
In this code:
void foo(int *arr)
{
arr = (int[]){-2, -7, 1, 255};
}
arr
is set to point to the compound literal, but arr
is only a function parameter. It effectively ceases to exist when the function returns.
In this code:
int *my_array = (int[]){1, 2, 3};
foo(my_array);
if (my_array[2] != 1)
return -1;
When foo
is called, its parameter arr
is set to the value of my_array
. When arr
is changed inside foo
, it does not affect my_array
. my_array
will still be pointing to the start of (int[]){1, 2, 3}
. This would be true regardless of whether arr
is set to point to a compound literal, allocated memory, or anything else: Changing a parameter inside a function does not change the thing that was passed as an argument.
To get the pointer out of the function, you could either return it or you could pass a pointer to a pointer so that the function had the address of the pointer:
void foo(int **arr)
{
*arr = (int []) { -2, -7, 1, 255 };
}
int main(void)
{
int *my_array = (int []) { 1, 2, 3 };
foo(&my_array);
…
}
However, then foo
would be putting the address of its compound literal into a pointer that is used after the function ends. That is a situation where you ought to call malloc
to reserve memory and then copy the data into the allocated memory. Later, after the program is done with that data, it would call free
to release the memory.