Home  >  Q&A  >  body text

C++的引用问题

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,"@@@");
程序试图引用已经释放的内存。
我想问问到底为什么出错啊,原因是什么
求详解! 谢谢。。
引用感觉自己学的不好。。

迷茫迷茫2649 days ago288

reply all(2)I'll reply

  • 黄舟

    黄舟2017-04-17 11:59:17

    首先我们要知道C++引用是什么东西,其实它就是指针,只不过编译器给加了点语法糖和类型检查。

    语法糖让你不用写 * 和 ->
    类型检查导致引用只能在定义的时候绑定一次

    所以函数version3 等价于

    const string* version3(string *s1, const string* s2)
    {
      string temp;
      temp = *s2 + *s1 + *s2;
      return &temp;
    }
    

    函数version3中的temp是局部变量,所以函数退出时会调用string析构函数,temp对象占用的内存全部被释放。version3返回了一个指针,但是指针指向的对象已经析构了,这就是野指针啊。

    访问野指针指向的内存,轻则coredump,重则产生哭爹的逻辑错误。那代码中哪一行会访问野指针指向的内存呢,就在下面这行代码中:

    result=version3(input,"@@@")

    这里会调用 string的copy assignment, 必然牵涉到拷贝,于是要访问已经被释放的内存。

    所以致命的一步就发生在 string 的copy assignment函数内。

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 11:59:17

    temp 在const string & version3(string & s1,const string &s2)中是在栈上 所以返回他的引用是有问题的 因为temp在方法执行完后就已经被释放掉了.

    reply
    0
  • Cancelreply