结论:函数可以返回局部变量的值,但是不能返回指向栈内存的指针。
原因:
局部变量的作用域为函数内部,函数执行结束,操作系统会自动释放栈上的局部变量。并且函数返回的是局部变量的值拷贝。
但是如果返回局部变量的地址,那么返回的是该局部变量地址的值拷贝,但是函数运行结束,该拷贝指针所指向的栈内容已经被释放即为野指针,对野指针所指向内容的操作都会造成段错误.
函数是可以返回指向堆内存的指针,但是这需要在调用者在函数外手动进行内存的释放,可以通过指针传递来解决。
一般来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。
因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。
总结如下:
1 |
#include <iostream> #include <stack> #include <string.h> using namespace std; int fun0(){ int cc = 5; //在栈上分配内存 //可以返回局部变量,因为返回的是cc是拷贝一份的值,fun0()函数结束后,cc释放掉,副本值可以返回正确的值. return cc; } int* fun(){ int cc = 5;//在栈上分配内存 //返回cc的地址,fun()函数结束时,cc在栈上分配的内存会出栈,释放掉,这时返回的地址是一个野指针 return &cc; } int* fun1(){ int cc = 5; int *p = &cc; return p; } int* fun2(){ int cc = 66;//在栈上分配内存 int *p = &cc; return p;//返回cc的地址,fun()函数结束时,cc在栈上分配的内存会出栈,释放掉,这时返回的地址是一个野指针 } int main(){ //OK int cc = fun0(); printf("%d\n", cc); //Error int *m = fun(); printf("%d\n", *m); #if 0 //way 1:OK;这里虽然是正确的,但是下面的栗子确实错误的,概率问题,不能返回局部变量的指针 int *p = fun1(); printf("%d\n", *p); int *q = fun2(); printf("%d\n", *q); #else //way 2:Error ;可能分配堆栈顺序问题,返回结果都是66 int *p = fun1(); int *q = fun2(); printf("%d\n", *p); printf("%d\n", *q); #endif return 0; } 总结:不能返回局部变量的指针是有前提的: 1.可以返回指针指向全局变量、堆上分配(new,malloc)、常量区(如:"123")、静态区(static)的指针 2.不能返回指向栈的指针,因为栈随函数执行完成,出栈自动回收内存,会造成指向的是一个无效地址,导致段错误 |