9

Consider the following code.

#include<stdio.h>
int *abc(); // this function returns a pointer of type int

int main()
{
    int *ptr;
    ptr = abc();
    printf("%d", *ptr);
    return 0;
}

int *abc()
{
    int i = 45500, *p;
    p = &i;
    return p;
}

Output:

45500

I know according to link this type of behavior is undefined. But why i am getting correct value everytime i run the program.

5
  • Because undefined behaviour is allowed to do that. By the way, I don't see anything wrong with this question. Upvoted. Commented Sep 7, 2016 at 15:11
  • 3
    Its because your program is very simple. Try to insert a call to some other function between calls to abc() and printf() Commented Sep 7, 2016 at 15:11
  • 3
    So what? "Undefined" doesn't mean "random"... Commented Sep 7, 2016 at 15:14
  • Add this, immediately after the call to abc() and before the existing printf: printf("Test string %d %d %d %d\n", 1, 2, 3, 4). Then see what happens :) Commented Sep 7, 2016 at 15:20
  • Call abc() then call def() and after check what p points to... You could make i static, as long as there is no reentrance issue... (e.g. threads modifying *p ...) Commented Sep 7, 2016 at 15:34

2 Answers 2

6

Every time you call abc it "marks" a region at the top of the stack as the place where it will write all of its local variables. It does that by moving the pointer that indicates where the top of stack is. That region is called the stack frame. When the function returns, it indicates that it does not want to use that region anymore by moving the stack pointer to where it was originally. As a result, if you call other functions afterwards, they will reuse that region of the stack for their own purposes. But in your case, you haven't called any other functions yet. So that region of the stack is left in the same state.

All the above explain the behavior of your code. It is not necessary that all C compilers implement functions that way and therefore you should not rely on that behavior.

Sign up to request clarification or add additional context in comments.

17 Comments

This is very implementation specific.
Yes, I am only explaining the behavior to satisfy his curiosity.
As an example Keil C compiler for i8051: It allocates locals in data segment by building a calling tree at link time, so stack is used only to pass control
@Serge: How does it handle recursion?
Which is where the spec meets reality. I've had this discussion with others. Sometimes, there is no way to create a conformant compiler for a given chip architecture. That doesn't mean an almost-compliant compiler isn't better than raw assembler. Also, those compilers are usually C90
|
2

Well, undefined behavior is, undefined. You can never rely on UB (or on an output of a program invoking UB).

Maybe, just maybe in your environment and for your code, the memory location allocated for the local variable is not reclaimed by the OS and still accessible, but there's no guarantee that it will have the same behavior for any other platform.

2 Comments

what's UB ?? pls define
@Cody UB -> undefined behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.