这是代码,
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"
仍然在堆中,对吧?
答案 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
中为您提供有效数据。
如果局部变量不是静态的,那么当函数返回时,相同的测试会失败,因为变量会消失。