为本地指针初始化占用相同内存的函数?

时间:2014-04-20 22:31:10

标签: c pointers scope

以下示例来自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;
}

输出:

$ ./static 

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

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

 [Windows] [0x7fff705e9378]
$

为什么func1_Str()func2_Str()会使用相同的地址初始化char *p?是否与指针同名的事实有关?

2 个答案:

答案 0 :(得分:1)

如果为代码启用了一些警告,一个好的编译器会警告你“正在返回一个局部变量的地址”(或类似的东西)。

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

在此示例中,p位于堆栈上,并使用常量字符串"Linux"的地址进行初始化。然后,您将在堆栈上返回p的地址,并在此之后立即重置堆栈指针,此时函数将返回到调用方。然后,当您调用func2_Str时,堆栈上的相同位置将重新使用p  在func2_Str。堆栈就像厨房里的一叠盘子,当你打电话给一个功能时,你把新的牌子放上,你在回来时再次关闭。

所以,是的,你会得到两个指针的相同地址,因此,当然,他们指向的任何东西都是一样的。

变量的名称与它无关(如果您尝试将其中一个重命名为其他内容的简单实验,您会发现)。你也可以这样做:

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

你可能(可能)看到p的值已经改变,因为我们现在需要另外四个字节。

(我也觉得你的系统与链接中的例子完全相同的地址是相当惊人的 - 你实际上是自己编译的,还是只是从网站上复制和粘贴) (当然,如果您实际上已经阅读了您链接的网站上的文字,那么您会理解这一点)

答案 1 :(得分:1)

恰好,func1_Strfunc2_Str的堆栈内存要求完全相同。因此,pfunc1_Str使用的内存位置恰好与pfunc2_Str使用的内存位置一致。