局部变量的作用域在函数的内部,函数返回后,局部变量内存已经释放掉了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。故函数是可以返回局部变量的。
但是如果函数返回的是局部变量的地址(指针)的话,程序运行就会报错。由于只是把指针(地址)复制后返回了,而指针指向的内存(存储的内容)已经被释放了,这样指针无访问该内存的权限,调用后就会报错。
准确的说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。
案例一:
#include <iostream>
using namespace std;
char* GetStr0()
{
char* ch = "hello world!";
return ch;
}
void main()
{
char* p = nullptr;
p = GetSt0();
cout << "GetStr0() : " << p << endl;
}
运行返回"hello world!",由于"hello world!"是一个字符串常量,存放在只读数据段(常量区),把该字符串常量存放的只读数据段的首地址赋值给了指针,所以GetStr函数退出时,该字符串常量的内存不会被系统回收,故能够通过指针顺利无误的访问。
案例二:
"hello world!"是局部变量存放在栈中。当GetStr1()函数退出时,栈要清空,局部变量的内存也被清空了,所以函数返回的是一个已被释放的内存地址,打印出来的是乱码。
案例三:
int func()
{
int a;
....
return a; //可以
}
int * func()
{
int a;
....
return &a; //无意义,内存释放
}
局部变量可分为局部自动变量和局部静态变量,由于a返回的是值(指针指向的内容),故无论是自动还是静态个局部变量是可以的返回的,因为这时返回的是局部变量的值。但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量被释放了,该指针指向一个已经不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存期从定义起到程序结束。