看以下例子:
#include <stdio.h>
char *return_str()
{
char *p_str="hello world!"; //指针指向常量区
return p_str;
}
void main()
{
char *pstr;
pstr=return_str();
printf("%s\n", pstr);
system("pause");
}
运行输出如下:
由运行结果可知该函数不存在任何问题,因为"hello world!"是一个字符串常量,存放在常量区,接着把该字符串常量存放的常量区的首地址赋值给了指针,所以return_str函数退出时,该字符串常量所在内存区域不会被回收,因此能够通过指针成功进行访问。
但是,以下的程序就会存在问题:
#include <stdio.h>
char *return_str()
{
char p_str[]="hello world!"; //字符数组位于栈区
return p_str;
}
int main()
{
char *pstr;
pstr=return_str();
printf("%s\n", pstr);
return 0;
}
运行输出如下:
由于"hello world!"是一个字符串常量,存放在常量区,可是若把一个字符串常量赋值给了一个局部变量(字符型数组),首先将字符串常量从常量区拷贝到栈区,即该局部变量存放在栈上,这是与前例存在最本质的区别,当return_str函数退出时,栈要清空,局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以打印出来的是乱码。
如果函数的返回值必须是一个局部变量的地址时,那么该局部变量一定要申明为static类型。如下:
#include <stdio.h>
char *return_str()
{
static char p_str[]="hello world!"; //字符数组位于全局区
return p_str;
}
int main()
{
char *pstr;
pstr=return_str();
printf("%s\n", pstr);
return 0;
}
输出如下:
由于"hello world!"是一个字符串常量,存放在常量区,但若把一个字符串常量赋值给了一个静态局部变量(字符型数组),首先将字符串常量从常量区拷贝到全局区,static修饰局部变量时,表明在函数调用结束时不销毁,他的生命期:从第一次调用开始,到main结束,所以return_str函数退出时,该字符串常量所在内存区域不会被回收,故能够通过指针成功进行访问。
结论:子函数的返回值不能返回指向“栈内存”的“指针”,由于该内存在函数体被调用结束时自动释放,若再次访问该内存,系统将会报错,函数返回乱码。