What does fflush () do in terms of dangling pointers?

I came across this page which illustrates common ways to create dangling points.

The code below is used to illustrate dangling pointers by returning the address of a local variable:

// The pointer pointing to local variable becomes  
// dangling when local variable is static.
#include<stdio.h>

int *fun()
{
    // x is local variable and goes out of scope 
    // after an execution of fun() is over.
    int x = 5;

    return &x;
}

// Driver Code
int main()
{
    int *p = fun();
    fflush(stdout);

    // p points to something which is not valid anymore
    printf("%d", *p);
    return 0;
}

      

When I run this, this is the compiler warning I get (as expected):

 In function 'fun':
12:2: warning: function returns address of local variable [-Wreturn-local-addr]
  return &x;
  ^

      

And this is the result I am getting (so far):

32743

      

However, when I comment out the fflush (stdout) line, this is the output I get (with the same compiler warning):

5

      

What is the reason for this behavior? How exactly does the presence / absence of the fflush command causing this change change?

+3


source to share


2 answers


Returning a pointer to an object on the stack is bad, as you mentioned. The reason you only see a problem with your call fflush()

is because the stack is not changed if it doesn't exist. That is, 5

still in place, so dereferencing the pointer still gives you 5

. If you call a function (almost any function, perhaps) between fun

and printf

, it will almost certainly overwrite that stack location, causing subsequent lookups to return any unwanted effect that function left there.



+3


source


This is because the call fflush(stdout)

is pushed onto the stack where it x

was.

Let me explain. The assembly language stack (which all programming languages โ€‹โ€‹end up running one way or another) is typically used to store local variables, return addresses, and function parameters. When a function is called, it pushes these things onto the stack:

  • the address where to continue executing the code after the function ends.
  • parameters for the function in the order specified by the conditional convention used.
  • local variables used by the function.


These things are then popped off the stack, one by one, simply changing where the processor thinks the top of the stack is. This means that the data still exists, but it is not guaranteed to continue to exist.

Calling another function after fun()

overwrites previous values โ€‹โ€‹above the top of the stack, in this case with a value stdout

, and so the value of the pointer reference changes.

Without calling another function, the data remains there and remains valid when the pointer is dereferenced.

0


source







All Articles