include
include using namespace std;
string version1(const string & s1,const string & s2);
const string & version2(string & s1,const string & s2);
const string & version3(string & s1,const string & s2);
int main()
{
string input;
string copy;
string result;
cout<<"Enter a string : ";
getline(cin,input);
copy=input;
cout<<"Your string as entered: "<<input<<endl;
result=version1(input,"***");
cout<<"Your string enhanced: "<<result<<endl;
cout<<"Your original string: "<<input<<endl;
result=version2(input,"###");
cout<<"Your string enhanced: "<<result<<endl;
cout<<"Your original string: "<<input<<endl;
cout<<"Resetting original string.\n";
input =copy;
result=version3(input,"@@@");
cout<<"Your string enhanced: "<<result<<endl;
cout<<"Your original string: "<<input<<endl;
return 0;
}
string version1(const string & s1,const string & s2)
{
string temp;
temp=s2+s1+s2;
return temp;
}
const string & version2(string & s1,const string & s2)
{
s1=s2+s1+s2;
return s1;
}
const string & version3(string & s1,const string &s2)
{
string temp;
temp=s2+s1+s2;
return temp;
}
相信大家都知道这段代码 是C++ prime plus里的 第八章
书上说 第三个函数版本是致命缺陷,执行第三个函数时将崩溃。
问题是由下面的复制语句引发的:
result=version3(input,"@@@");
程序试图引用已经释放的内存。
我想问问到底为什么出错啊,原因是什么
求详解! 谢谢。。
引用感觉自己学的不好。。
首先我们要知道C++引用是什么东西,其实它就是指针,只不过编译器给加了点语法糖和类型检查。
语法糖让你不用写 * 和 ->
类型检查导致引用只能在定义的时候绑定一次
所以函数version3 等价于
函数version3中的temp是局部变量,所以函数退出时会调用string析构函数,temp对象占用的内存全部被释放。version3返回了一个指针,但是指针指向的对象已经析构了,这就是野指针啊。
访问野指针指向的内存,轻则coredump,重则产生哭爹的逻辑错误。那代码中哪一行会访问野指针指向的内存呢,就在下面这行代码中:
这里会调用 string的
copy assignment
, 必然牵涉到拷贝,于是要访问已经被释放的内存。所以致命的一步就发生在 string 的
copy assignment
函数内。