Question

In the following example from here

#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
    char **ptr1 = NULL;
    char **ptr2 = NULL;

    ptr1 = func1_Str();
    printf("\n [%s] :: func1_Str() address = [%p], its returned address is [%p]\n",*ptr1,(void*)func1_Str,(void*)ptr1);

    ptr2 = func2_Str();
    printf("\n [%s] :: func2_Str()address = [%p], its returned address is [%p]\n",*ptr2,(void*)func2_Str,(void*)ptr2);

    printf("\n [%s] [%p]\n",*ptr1,(void*)ptr1);

    return 0;
}

char** func1_Str()
{
    char *p = "Linux";
    return &p;
}

char** func2_Str()
{
    char *p = "Windows";
    return &p;
}

Output:

$ ./static 

 [Linux] :: func1_Str() address = [0x4005d5], its returned address is [0x7fff705e9378]

 [Windows] :: func2_Str()address = [0x4005e7], its returned address is [0x7fff705e9378]

 [Windows] [0x7fff705e9378]
$

Why would func1_Str() and func2_Str() use the same address for initializing char *p? Does it have something to do with the fact that the pointers are named equally?

Was it helpful?

Solution

If you enable some warnings for your code, a good compiler will warn you that you are "returning the address of a local variable" (or something like that).

char** func1_Str()
{
    char *p = "Linux";
    return &p;
}

In this example, p is located on the stack, and initialized with the address of the constant string "Linux". You are then returning the address of p on the stack, and immediately after that, the stack pointer is reset when the function returns to the caller. When you then call func2_Str, the same location on the stack is then reused p in func2_Str. The stack is like a stack of plates in a kitchen, you put new ones on when you call into a function, you take the off again when returning.

So, yes, you'll get the same address for both of your pointers, and because of that, anything they point to will be the same as well, of course.

The name of the variable has nothing to do with it (as you would have found out if you tried the simple experiment of renaming one of them to something else). You could also do something like this:

char** func1_Str()
{
    char *q = "Windows";
    char *p = "Linux";
    return &p;
}

And you'd (probably) see that p's value has changed, because we now need another four bytes.

(I also find it rather amazing that your system gets EXACTLY the same address as the example in the link - are you actually compiling this yourself, or just copying and pasting from the site) (Of course, if you had actually read the text on the site you linked, you would have understood that)

OTHER TIPS

It so happens that that the stack memory requirements for func1_Str and func2_Str are exactly the same. As a result, the memory location used for p in func1_Str happened to coincide with the memory location used for p in func2_Str.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top