返回一个指向静态变量的本地指针

时间:2012-02-24 01:02:50

标签: c static

这是代码,

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

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

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

通常,返回本地指针是错误的,就像我在bar中所做的那样,但现在c指向由static返回的foo var,是不是正确返回c中的本地变量bar

我试过,printf正确的价值,但我不明白它是如何运作的。我想,当bar()完成时,变量c应该消失,这应该使printf打印未定义的东西,对吗?

跟进

char *c是一个局部变量,如果char *c = "abcde";,我假设:c是一个局部变量,它驻留在函数的堆栈中,而"abcde"是一个常量变量它驻留在常量区域(堆的一部分?)中,所以当bar()完成时,c消失,但"abcde"仍然在堆中,对吧?

4 个答案:

答案 0 :(得分:10)

变量c只是一个指针。从函数返回本地指针并没有错,你总是这样做。例如,在结果中存储malloc的结果时,指针是本地的,但指向的存储不是。但是,将指针返回到本地存储是错误的。由于在您的示例中,c从不指向本地分配的数据,因此您的代码可以正确编写。

编辑(响应跟进)

  

“abcde”是一个常量var,它位于常量区域(堆的一部分?)

常量区域通常不是堆的一部分,它是一个单独的区域,通常与存储程序机器代码的区域相邻。

  

c消失了,但是“abcde”仍然存在于堆中,对吗?

“abcde”保留在常量区域中,而不是在堆中,但概念是正确的:指向该常量的指针在程序的整个运行时间内保持有效。

答案 1 :(得分:1)

返回c,即foo() s,即"abcde"的地址。 bar返回后消失的是char *c = foo();时存储该值的空间。

所以,是的,这是正确的。

答案 2 :(得分:1)

你的直觉是正确的,但你似乎遇到的问题是:

C中有三种存储类型,

自动普通本地存储)它们存在于堆栈中,并且在返回函数后,指向此数据的指针不再有效。

动态(想想malloc)在调用free()之后,存在于堆中的指针和指向此数据的指针不再有效。

静态它位于数据段中(因此它不会消失)。

由于s是一个静态变量,因此它会持续整个程序的生命周期。所以,当foo返回时,它不会消失。

编辑:我应该补充说还有注册,但大多数编译器都忽略了这一点。

答案 3 :(得分:0)

函数内部的静态局部变量将保留在内存中直到应用程序结束,并且在函数返回时不会消失。这就是为什么拥有一个指向静态变量的指针,即使在函数printf之外,也会在foo中为您提供有效数据。

如果局部变量不是静态的,那么当函数返回时,相同的测试会失败,因为变量会消失。