Created
April 6, 2017 18:54
-
-
Save bhanubais/56a2ae23b36f33e91598fa3fad2e914b to your computer and use it in GitHub Desktop.
C language pointer issue. Why I am getting 20 instead of 7 as a value of *nn in following code?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
int *ptr(int n); | |
void nothing(int n1); | |
int main(void) { | |
int *nn = ptr(7); | |
nothing(20); | |
printf("*nn is %d\n", *nn); // why I am getting 20 instead of 7? | |
} | |
int *ptr(int n) { | |
int *p = &n; | |
printf("p is %d\n", *p); | |
return p; | |
} | |
void nothing(int n1) { | |
// int n2 = n1; | |
printf("n1 is %d\n", n1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When you call
ptr(7)
, then the current stack pointer and a few other pieces of information like the code position to which to return are stored on the stack, then the parameters and variables liken
andp
are stored on the stack. Parametern
receives a copy of the7
you passed to the function.You now return a pointer to parameter
n
, jump back to the calling code, and the stack is reset to its previous size. The returned pointer is now pointing to a part of the stack that's not in use, but there's no reason to overwrite its content, so it keeps the 7. That space belongs to the programme, so there's also no segmentation fault.If you now call
printf
, the*nn
is evaluated to 7, and prints that value.If you call
nothing(20)
beforeprintf
, its parameter is stored in the same place as the parameter toptr
before, so it overwrites the value. Now,*nn
would evaluate to 20.The nice tool
valgrind
(actually a collection of tools) will complain in your case, I put the output below the comment.What can you learn there? Don't store/pass pointers to structures that no longer exist, either because they are defined on a stack and the defining code block has been finished, or have been allocated dynamically and have been freed since then. Many security problems are created that way ("use after free").
Executive summary: You're reading from address stored in
nn
withnn
pointing to a space that's currently marked as "unused". Could have any value.