For better understanding of what's happening here, renaming the ptr
parameter of fun()
function to fun_ptr
void fun(int* fun_ptr)
^^^^^^^
When you call fun()
function
int* ptr = NULL;
fun(ptr);
the value of argument ptr
will be assigned to fun()
function parameter fun_ptr
. Its similar to this
fun_ptr = ptr;
ptr
is NULL
, so the fun_ptr
will be assigned NULL
. Whatever changes you do in fun_ptr
inside fun()
function will stay within fun()
function block because the scope of identifier within the list of parameter declarations in a function definition has block scope which terminate when function returns.
If you want to make changes to a pointer variable in another function, you have to pass the address of that pointer variable to the calling function. In context of your program, it should be
void fun(int** ptr) {
int a = 5;
*ptr = &a;
// *ptr will be the pointer passed as argument i.e. assign anything
// to *ptr means you are making changes to pointer passed as argument
.....
.....
}
int main(void)
{
int* ptr = NULL;
fun(&ptr);
.....
.....
return 0;
}
Even after making these changes your program will have Undefined Behaviour because it is accessing address of local variable outside of its scope. Variable a
is a local(automatic) non-static variable and its lifetime is limited to its scope i.e. the block in which it has been declared. Any attempt to access it outside of its lifetime lead to undefined behaviour.
To resolve this, allocate memory to pointer ptr
and assign the value of a
to it. Or, you can declare a
as static
variable. The lifetime of a static variable is entire run of the program. You can do:
#include <stdio.h>
#include <stdlib.h>
void fun1 (int** ptr) {
static int a = 5;
*ptr = &a;
printf("fun1(): address: %p, value: %d\n", (void *)&a, a);
printf("fun1(): address: %p, value: %d\n", (void *)*ptr, **ptr);
}
void fun2 (int** ptr) {
int a = 5;
*ptr = malloc (sizeof (int));
if (*ptr == NULL) {
fprintf (stderr, "Failed to allocate memory\n");
exit (EXIT_FAILURE);
}
**ptr = a;
printf("fun2(): address: %p, value: %d\n", (void *)&a, a);
printf("fun2(): address: %p, value: %d\n", (void *)*ptr, **ptr);
}
int main (void) {
int* ptr1 = NULL;
int* ptr2 = NULL;
fun1(&ptr1);
printf("main(): address: %p\n", (void *)ptr1);
printf("main(): address: %p, value: %d\n", (void *)ptr1, *ptr1);
fun2(&ptr2);
printf("main(): address: %p\n", (void *)ptr2);
printf("main(): address: %p, value: %d\n", (void *)ptr2, *ptr2);
// Once done with dynamic allocated memory, release it
free(ptr2);
return 0;
}