-1

I was trying out some pointer and function interaction and found out this behavior. The first printf prints 100 but the second printf prints 0!

Can somebody help me understand why?

void ptr_change (int **p)
{       
    int y = 100;
    *p = &y;
}

int main ()
{

    int x = 7;
    int *p = &x;
    ptr_change(&p);
    printf("\nPtr = %d", *p);
    printf("\nPtr = %d", *p);
    return 0;

}

Compile:

gcc ptr2.c

Run and give output:

./a.out 

Ptr = 100
Ptr = 0
alk
  • 69,737
  • 10
  • 105
  • 255

4 Answers4

3

y is an automatic local variable which will no longer exist after the function returns and you are assigning the address of an automatic local variable to the pointer.
In the main function you are dereferencing a pointer which no longer points to a valid location. This invokes undefined behavior. You can't expect anything good once there is undefined behavior of your code.

honk
  • 9,137
  • 11
  • 75
  • 83
haccks
  • 104,019
  • 25
  • 176
  • 264
2

You return the address of an automatic variable from a procedure. The variable is no longer valid after the function returns. What happens next is called Undefined Behavior, however, an explanation for Intel machines and e.g. VC2008 is:

ptr_change(&p);

This places in p the address of the local variable y. After return from function ptr_change the stack space used by the function is released.

printf("\nPtr = %d", *p);

This first printf re-uses the stack space used earlier by ptr_change. It pushes 2 parameters onto the stack. The first parameter overwrites the stack space used by &p in your function call. y is not yet overwritten. The *p parameter of printf gets this value and pushes it onto the stack. The call to printf now overwrites int y.

printf("\nPtr = %d", *p);

As int y has been overwritten in the previous cal to printf, this call to printf prints garbage.

Note that any other form of undefined behavior is possible!

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
1

The value of y in

void ptr_change (int **p)
{       
    int y = 100;
    *p = &y;
}

exists only temporary on stack as an automatic variable. Once the function returns that location is not longer valid.

Compare the following program which passes pointer to the variable a and initializes pointer p.

#include<stdio.h>

void ptr_change2 (int **p, int *a)
{       
    *p = a;
}

int main ()
{
    int x = 7;
    int z = 8;

    int *p = &x;

    printf("\nPtr = %d", *p);

    ptr_change2(&p,&z);

    printf("\nPtr = %d", *p);

    return 0;
}

Output:

Ptr = 7
Ptr = 8
sg7
  • 6,108
  • 2
  • 32
  • 40
-3
*p = &y 

is incorrect, you're assigning the address of y to the value of p.

try this instead:

p = &y

they will now have the same base address.

y = 100;

then print the pointer value of p

printf("%d", *p);
utsav0195
  • 1
  • 4