函数调用后指针的值是否仍然可用?
Value of pointer still available after function call?
#include <stdio.h>
//needed so we can use the built in function strcpy
#include <string.h>
int main()
{
char* foo()
{
char* test="Hello";
printf("value of test: %p\n",test);
return test;
}
//why does this work? is test off the stack, but Hello in mem is still there?
work=foo();
printf("value of work after work has been initalized by foo(): %p\n",work);
printf("%s\n",work);
}
在上面的代码中,'work=foo()',我注意到 'test' 和 'work' 的值是相同的。这意味着它们指向内存中的同一点,但是在函数调用之后 'test' 超出范围并且不允许访问。为什么 'test' 不允许访问,但它的值/内存位置是?我假设 'test' 由于函数调用后离开堆栈而不允许访问?我是指针的新手,所以如果我的术语或任何内容不正确,请纠正我。
嵌套函数不是标准的 c,它是 gcc 的 extension,因此您的代码不会总是编译,但它确实可以工作,因为 gcc 扩展。
之所以如此,与嵌套函数无关,如果您执行以下操作,您将观察到完全相同的行为
#include <stdio.h>
char *foo()
{
char* test="Hello";
printf("value of test: %p\n",test);
return test;
}
int main()
{
// why does this work? is test off the stack, but Hello in mem is still there?
char *work = foo();
printf("value of work after work has been initalized by foo(): %p\n",work);
printf("%s\n",work);
return 0;
}
函数 foo()
是 return 将地址转换为一个静态字符串,该字符串在程序的整个生命周期中都会保留。
我改为创建一个数组,你会 return 局部变量的地址,这是不可能的
#include <stdio.h>
int main()
{
char *foo()
{
char test[] = "Hello";
printf("value of test: %p\n", test);
printf("value of foo: %p\n", foo);
return test;
}
// why does this work? is test off the stack, but Hello in mem is still there?
char *work = foo();
printf("value of work after work has been initalized by foo(): %p\n",work);
printf("%s\n",work);
return 0;
}
编译器会在最后一种情况下发出警告,printf("%s\n",work);
会打印垃圾,尽管 printf("value of work after work has been initalized by foo(): %p\n",work);
会打印相同的地址,数据将与 [=15= 的堆栈帧一起被销毁].
尽管有非标准的嵌套函数定义,但您在这里看到的行为是因为字符串常量 "Hello" 是程序可执行文件的一部分,并且在程序执行时与程序代码一起映射到内存中.该指针只是在运行时保存字符串在内存中的存储位置。该常量字符串是程序的一部分,不会像堆栈变量那样 spring 存在和消失。栈变量是"Hello"的地址,通过return值传递给调用栈。
您的 foo() 函数正在返回静态字符串 "Hello",它通常存储在程序文本段中。
由于实际的字符串存储不在堆栈中,因此它在函数调用后仍然存在。
超出范围的变量 test
只是一个指针,由于该指针值返回给调用者,调用者现在拥有字符串存储的位置。
(如前所述,C语言中不允许嵌套函数。)
然而,在 C 语言中,字符串文字是具有静态存储持续时间的对象。它们未存储 "on the stack",正如您似乎错误地假设的那样。它们存储在静态内存中,就像全局变量一样。
你的foo
函数的代码等同于
static char unnamed_string_literal[] = { 'H', 'e', 'l', 'l', 'o', '[=10=]' };
char* foo()
{
char* test = unnamed_string_literal;
printf("value of test: %p\n", test);
return test;
}
这就是为什么只要您的程序运行,字符串文字 "Hello"
的值将始终可用。每次你调用你的foo
,你都会得到完全相同的指针值。
#include <stdio.h>
//needed so we can use the built in function strcpy
#include <string.h>
int main()
{
char* foo()
{
char* test="Hello";
printf("value of test: %p\n",test);
return test;
}
//why does this work? is test off the stack, but Hello in mem is still there?
work=foo();
printf("value of work after work has been initalized by foo(): %p\n",work);
printf("%s\n",work);
}
在上面的代码中,'work=foo()',我注意到 'test' 和 'work' 的值是相同的。这意味着它们指向内存中的同一点,但是在函数调用之后 'test' 超出范围并且不允许访问。为什么 'test' 不允许访问,但它的值/内存位置是?我假设 'test' 由于函数调用后离开堆栈而不允许访问?我是指针的新手,所以如果我的术语或任何内容不正确,请纠正我。
嵌套函数不是标准的 c,它是 gcc 的 extension,因此您的代码不会总是编译,但它确实可以工作,因为 gcc 扩展。
之所以如此,与嵌套函数无关,如果您执行以下操作,您将观察到完全相同的行为
#include <stdio.h>
char *foo()
{
char* test="Hello";
printf("value of test: %p\n",test);
return test;
}
int main()
{
// why does this work? is test off the stack, but Hello in mem is still there?
char *work = foo();
printf("value of work after work has been initalized by foo(): %p\n",work);
printf("%s\n",work);
return 0;
}
函数 foo()
是 return 将地址转换为一个静态字符串,该字符串在程序的整个生命周期中都会保留。
我改为创建一个数组,你会 return 局部变量的地址,这是不可能的
#include <stdio.h>
int main()
{
char *foo()
{
char test[] = "Hello";
printf("value of test: %p\n", test);
printf("value of foo: %p\n", foo);
return test;
}
// why does this work? is test off the stack, but Hello in mem is still there?
char *work = foo();
printf("value of work after work has been initalized by foo(): %p\n",work);
printf("%s\n",work);
return 0;
}
编译器会在最后一种情况下发出警告,printf("%s\n",work);
会打印垃圾,尽管 printf("value of work after work has been initalized by foo(): %p\n",work);
会打印相同的地址,数据将与 [=15= 的堆栈帧一起被销毁].
尽管有非标准的嵌套函数定义,但您在这里看到的行为是因为字符串常量 "Hello" 是程序可执行文件的一部分,并且在程序执行时与程序代码一起映射到内存中.该指针只是在运行时保存字符串在内存中的存储位置。该常量字符串是程序的一部分,不会像堆栈变量那样 spring 存在和消失。栈变量是"Hello"的地址,通过return值传递给调用栈。
您的 foo() 函数正在返回静态字符串 "Hello",它通常存储在程序文本段中。
由于实际的字符串存储不在堆栈中,因此它在函数调用后仍然存在。
超出范围的变量 test
只是一个指针,由于该指针值返回给调用者,调用者现在拥有字符串存储的位置。
(如前所述,C语言中不允许嵌套函数。)
然而,在 C 语言中,字符串文字是具有静态存储持续时间的对象。它们未存储 "on the stack",正如您似乎错误地假设的那样。它们存储在静态内存中,就像全局变量一样。
你的foo
函数的代码等同于
static char unnamed_string_literal[] = { 'H', 'e', 'l', 'l', 'o', '[=10=]' };
char* foo()
{
char* test = unnamed_string_literal;
printf("value of test: %p\n", test);
return test;
}
这就是为什么只要您的程序运行,字符串文字 "Hello"
的值将始终可用。每次你调用你的foo
,你都会得到完全相同的指针值。