这里记录一下C++关于不能返回局部变量的指针的研究。关于C++不能返回局部变量的引用很好理解,这里就不探讨了。如下若有不对的,麻烦纠正一下,一块儿学习进步~。java
先总结一下吧:c++
C++Primer中这句话的含义我认为是我不要使用任何在栈内存中分配内存的变量的引用或者指针做为返回值,因为栈内存在方法执行完毕后会将栈内存释放,所以获得的返回值是指向的地址是无效的。数组
在Java中咱们能够随意的返回一个对象,以下:学习
//常量 public String getTest(){ String result="sadads"; return result; } //对象 public Test get(){ Test test=new Test(); return test; }
个人理解是因为对象分配的内存在堆上,而常量则记录在方法区(上述的例子的"sadads"),而不是在虚拟栈中进行的内存分配,随着一个方法的结束,虽然栈帧中的内存释放了,可是对象在GC回收以前仍然在堆中存活,更别说常量了。测试
而对于C++而言,局部变量可能有不少种,包括数组,基本变量,以及咱们本身写的对象,一一看下对应的返回局部变量指针的正确性。指针
首先咱们看下数组的形式:code
char* ee(){ char x[]="12323"; char*p=x; return p; } int main(int argc, const char * argv[]) { std::cout<<"----"<<*ee()<<std::endl; return 0; } //返回结果:----1
从上面结果能够看出结果是不对的,这是因为数组分配的内存存在于栈内存当中,x的生命结束,其所占内存被释放,p也被释放,返回回来的是被释放的内存,输出必然不正确。那若是咱们须要他返回正确的值,须要如何修改呢?其实也简单,主要是使用堆内存来消除栈内存的约束,或者使用实参方式记录地址,这里直接使用堆内存来距离:对象
char* ee(){ char* xx=new char[3]{'k','b'}; char*p=xx; return p; } int main(int argc, const char * argv[]) { std::cout<<"----"<<*ee()<<std::endl; return 0; } //输出结果:----k
这样就是正确的了。内存
const char* getChar(){ const char *p="2234"; return p; } int* getInt(){ int x=12; int* p=&x; return p; } int main(int argc, const char * argv[]) { std::cout<<*getInt()<<"----"<<*getChar()<<std::endl; return 0; } //返回结果:12----2
对于基本变量而言,因为常量都声明在常量区,在方法执行完毕后并不会随着栈内存的消除而销毁,因此返回对应指针是可行的。get
####返回对象的局部变量指针
std::string* geTest(){ std::string test="123"; std::string *p=&test; return p; }; //返回结果:没法识别
这里使用string对象当作测试的例子,获得了无效的结果,推测string对象在栈内存中进行了分配内存的操做,致使了对应的结果,再在堆上进行测试:
std::string* getTestV2(){ std::string* str=new std::string("123"); return str; } int main(int argc, const char * argv[]) { int k=12; std::cout<<*getTestV2()<<std::endl; return 0; } //输出结果为123
经过上述的方式,咱们就能够获得先前在文章前头的总结,可是这里有个疑问,当我写以下代码的时候:
const char* getChar(){ std::string str="2234"; const char *p=str.c_str(); return p; }
发现能返回正确的结果,这个就有点懵逼了,先留在文章这里吧,这种问题仍是须要深刻理解C++后才能解答,学习初期先放在着,待往后了解后解答。