我在c++学习心得(1)中讲到这条: 在函数返回值为地址或引用时应该注意返回值不能是局部变量,应该是全局变量、静态变量等,静态变量(只在定义的局部函数里面可见)和全局变量共享全局数据区,在整个函数运行期间都存在,虽然用局部变量暂时可以得到正确的答案,如: #include <iostream.h>
int *f(int x,int y) { int *z; int temp=x+y; z=&temp; return z; }
int f1() { cout<<"what wrong?"<<endl; return 0; }
int main() { int a,b; int *c; cin>>a>>b; c=f(a,b); cout<<*c<<endl; f1(); cout<<*c; return 0; }
这个函数如果输入2,3则输出是: 5 what wrong? -858993460
调用函数f1后再输出的c所指向的值是一个不确定的值,因为这个时候函数f()已经结束,它用来返回的临时变量也在程序做了一些别的事情后被覆盖掉或释放。
让我们来看这个很有趣的程序: #include <iostream.h> int *z;
int *f(int x,int y) { int temp=x+y; z=&temp; return z; }
int f1() { cout<<"what wrong?"<<endl; return 0; }
int main() { int a,b; int *c; cin>>a>>b; c=f(a,b); cout<<*c<<endl; f1(); cout<<*c; return 0; }
这里把z定义为全局的整形指针变量,然后把局部变量中x+y的值所指的地址给z返回,z为全局变量应该不存在上面临时变量被释放的情况,但实际上运行的到的结果出乎意料,还是: 5 what wrong? -858993460
问题出在哪里?开始的时候我百思不得其解,甚至问老师老师也不太清楚,后来在网友的帮助下(看样子在网上学习很有用的)得到了答案,原来在函数f()中,temp是局部变量,在函数返回后它栈里面的值都要被释放,而指针z是指向局部变量temp的,所以得到上面的结果,于是将f()改成: int *f(int x,int y) { *z=x+y; return z; }
再运行原以为可以得到正确的结果,但运行的时候出错了,再想想,原来定义全局指针变量z的时候并没有给它赋初值,这个时候指针的指向是不定的,所以运行时会出错,于是将定义改成int *z=new int;只是此时z成了堆中的数据,不再是放在全局数据区里面的了。
要想让全局数据区里面的数据返回被调函数的地址,可以把上面的全局变量声明改成int z;,函数f(x,y)中改成z=temp;return &z;就可以了。
|