-1

I have an idea on dangling pointer. I know that the following program will produce a dangling pointer.But I couldnt understand the output of the program

char *getString()
{
        char str[] = "Stack Overflow ";
        return str;
}
int main()
{
        char *s=getString();
        printf("%c\n",s[1]);
        printf("%s",s);    // Statement -1
        printf("%s\n",s);  // Statement -2
        return 0;
}

The output of the following program is t if only Statement-1 is there then output is some grabage values if only Statement-2 is there then output is new line

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Teja
  • 109
  • 4
  • 12
  • Once you're done digesting the answers below, consider why changing only a few things in your program and it [**works**](http://ideone.com/BCYV1B). hint: `char *var` and `char var[]` are *not* synonymous outside the context of a function parameter. – WhozCraig Feb 03 '15 at 12:19

3 Answers3

2

Your code shows undefined behaviour, as you're returning the address of a local variable.

There is no existence of str once the getString() function has finished execution and returned.

As for the question,

if only Statement-1 is there then output is some grabage values if only Statement-2 is there then output is new line

No explanations. Once your program exhibits undefined behaviour, the output cannot be predicted, that's all. [who knows, it might print your cell phone number, too, or a daemon may fly out of my nose]

For simple logical part, adding a \n in printf() will cause the output buffer to be flushed to the output immediately. [Hint: stdout is line buffered.]

Solution:

You can do your job either of the two ways stated below

  • Take a pointer, allocate memory dynamically inside getString() and return the pointer. (I'd recommend this). Also, free() it later in main() once you're done.
  • make the char str[] static so that the scope is not limited to the lifetime of the function. (not so good, but still will do the job)
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • I just wanted to know the difference of answers for statement -1 and statement-2 and also I wanted to know why the answer for printf("%c\n",s[1]); is t – Teja Feb 03 '15 at 12:16
  • @user3673490 when the function end, the variable (and the pointer you are returning) gets out of scope. Since that memory is allocated on the *stack*, it will get corrupted. Hence it could print `t` or anything. – Sunil Bojanapally Feb 03 '15 at 12:18
  • @Sunil What happened over here is the second element of the array is t and when I tried to print the third element , yet I got the correct answer – Teja Feb 03 '15 at 12:22
0

your str in getString is a local variable, which is allocate on stack, and when the function returns, it doesn't exist anymore.

I suggest you rewrite getString() like this

char *getString()
{
        char str[] = "Stack Overflow ";
        char *tmp = (char*)malloc(sizeof(char)*strlen(str));
        memcpy(tmp, str, strlen(str));
        return tmp;
}

and you need to add

free(s);

before return 0;

In my case, pointer tmp points to a block memory on heap, which will exist till your program ends

you need to know more about stack and heap

Besides, there is still another way, use static variable instead

char *getString()
{
        static char str[] = "Stack Overflow ";
        return str;
}

PS: You get the correct answer for the following statement printf("%c\n",s[1]); is just a coincidence. Opera System didn't have time to do some clean work when you return from function. But it will

simon_xia
  • 2,394
  • 1
  • 20
  • 32
  • But why did I get the correct answer for the following statement printf("%c\n",s[1]); – Teja Feb 03 '15 at 12:18
  • @Teja you're not getting the jist of this. That you got *anything* is irrelevant. Your program invokes *undefined behavior*, and is thus ill-formed. You cannot rely on, predict, or draw any conclusions from that which has *no definition of behavior*. Don't confuse *observed* behavior with *defined* behavior. – WhozCraig Feb 03 '15 at 12:21
0

Array is returned as a pointer yet the array itself is the garbage after return from function. Just use static modifier.

What's concerning s[1] is OK. The point is, it's the first printf after getting the dangling pointer. So, the stack at this point is still (probably) intact. You should recall that stack is used for function calls and local variables only (in DOS it could be used by system interrupts, but now it's not the case). So, before the first printf (when s[1] is calc'ed), s[] is OK, but after - it's not (printf' code had messed it up). I hope, now it's clear.

Matt
  • 13,674
  • 1
  • 18
  • 27
  • BTW. To know exactly what's going on, one should use disassembler. Without it, everything written above is only a speculation. If, for example, the compiler decided to use one more local (i.e. stack) variable before the first printf for any possible reason, s[1] could be broken too. – Matt Feb 03 '15 at 12:35