1

The below program may print some garbage data as string is stored in stack frame of function getString() and data may not be there after getString() returns.

#include <stdio.h>
char *getString()
{
  char str[] = "abc"; 
  return str; 
}     
int main()
{
  printf("%s", getString());  
  return 0;
}

Output : Garbage Value.

Then why this below program is running fine and not printing a garbage value.

#include<stdio.h>
int *fun()
{
    int i=50;
    int *p=&i;
    return p;
}

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

Output : 50

Here also p is a pointer in function fun() and is stored in stack segment. I am confused here. Why the output is 50 and not the garbage value ?

Thanks.

Nerd
  • 43
  • 7
  • 1
    Since you've shown that there's no justification for expecting this to output "50", why isn't "50" a garbage value? – David Schwartz Jan 21 '17 at 12:22
  • Because if we change i=5, then it will print 5, and not the Garbage. It is printing the value of i that we are entering. – Nerd Jan 21 '17 at 12:26
  • Right, it's printing the value that you are entering. But you have no reason to expect it to do that. Thus it's behaving differently from the way you reasonably expect it to behave. So why do you say it's "running fine"? Not meeting our reasonable expectations is what buggy code does. It's behaving like buggy code, doing something other than what you reasonably expect. – David Schwartz Jan 21 '17 at 12:27
  • That is what my question is !! ... The first program prints garbage and second one should also print garbage in my opinion. Then why it is not printing garbage. That is my question . May be I am missing any concept of C standard related to that , please let me know. – Nerd Jan 21 '17 at 12:30
  • 1
    It's not doing what you expect it to do because it has a bug! That's what bugs do. That's why we avoid them. It takes many years of experience and lots of platform-specific knowledge to be able to accurately predict what code with these kinds of bugs will do. Until you have that expertise, you should not expect any particular results. It's going to do what it's going to do. – David Schwartz Jan 21 '17 at 12:31

3 Answers3

2

It shows the value from the stack, because that value isn't yet overwritten by something else. If we call function with arguments or create some stack variable, the value printed will change. Below prints 1, not 50, as latter was overwritten.

void bar(int a, int b, int c)
{
    char buf[] = "string";
    printf("%d-%d-%d-%s\n", a, b, c, buf);
}

int *fun()
{
    int i=50;
    int *p=&i;
    return p;
}

int main()
{
    int *q=fun();
    bar(1, 2, 3);
    printf("%d\n",*q);
    return 0;
}
ivan_onys
  • 2,282
  • 17
  • 21
1

Undefined behaviour means that the language standards do not specify any particular behaviour for that program invoking it. Your program has undefined behaviour. The specific output/behaviour is entirely platform specific and by no means reliable or valid; and, it includes "working as expected" too.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • I ran this program on gcc on linux environment, but it is still showing the same output. I think it is not platform specific.. – Nerd Jan 21 '17 at 12:35
  • I also said "not reliable or valid". I think you do not fully understand what undefinedness in C and C++ languages -- which is slightly different to its literal meaning in Enlgish. I suggest you review this: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html and https://en.wikipedia.org/wiki/Undefined_behavior – P.P Jan 21 '17 at 12:37
1

I havnt tried your code, but my take is

getString()

When getString() returns the bytes for "abc" are still stored in the previous stack memory. However the CPU will then prepare a call to printf which setups a new stack frame and thus overwrites "abc" with data specific to the printf call.

fun

the return value of fun is stored in the CPU accumulator register, so the call to printf never touches the memory of the previous stack frame.

CascadeCoder
  • 163
  • 10