Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return a local pointer which points to a static variable [duplicate]

Tags:

c

static

Here is the code,

char *foo()
{
    static char s[10] = "abcde";
    return s;
}

char *bar()
{
    char *c = foo();
    return c;
}

int main()
{
    printf("%s\n", bar()); 
}

Typically, it is wrong to return a local pointer as I did in bar, but now c points to a static var returned by foo, would it be correct to return a local var c in bar?

I tried, it printf the right value, but I don't understand how it works. I thought, when bar() finishes, the var c should vanish, which should make printf print undefined stuff, right?

Follow Up

char *c is a local var, if char *c = "abcde";, I assume this: c is a local var which resides in the function's stack, while "abcde" is a constant var which resides in the constants-area (part of the heap?), so when bar() finishes, c vanishes, but "abcde" still remains in the heap, right?

like image 364
Alcott Avatar asked Feb 24 '12 01:02

Alcott


3 Answers

Variable c is only a pointer. It is not wrong to return a local pointer from a function, you do it all the time. For example, when you store a result of malloc in a pointer, the pointer is local, but the storage it points to is not. It is, however, wrong to return a pointer to a local storage. Since in your example c never points to a locally allocated data, your code works correctly as written.

EDIT (in response to the Follow Up)

"abcde" is a constant var which resides in the constants-area (part of the heap?)

The constants area is not usually part of the heap, it is either a separate arrea, usually adjacent to the area where the machine code of your program is stored.

c vanishes, but "abcde" still remains in the heap, right?

"abcde" remains in the constants area, not in the heap, but the concept is correct: the pointer to that constant remains valid throughout the entire run-time of your program.

like image 160
Sergey Kalinichenko Avatar answered Nov 19 '22 01:11

Sergey Kalinichenko


The value of c is returned, which is foo() which is s which is the address of "abcde". What vanish after bar returns is the space in which that value was stored when you did char *c = foo();.

So, yes, it's correct.

like image 27
Metz Avatar answered Nov 19 '22 02:11

Metz


Your intuition is correct, but the issue you seem to be having is this:

There are three types of storage in C,

Automatic (the normal local storage) Which lives on the stack and pointers to this data are no longer valid after the return of the function.

Dynamic (think malloc) Which lives in the heap and pointers to this data are no longer valid after free() is called.

Static Which lives in the data segment (and so it doesn't disappear).

Since s is a static variable it lasts for the entire lifetime of the program. And so, no it will not vanish when foo returns.

Edit: I should add that there is also register, but that is largely ignored by most compilers.

like image 1
Avi Avatar answered Nov 19 '22 00:11

Avi