c++ 临时变量造成野指针

Oct 31, 2016


#include<iostream>
#include<cstring>
#include<string>
using namespace std;

class Test{
    public:
      Test(const char* p){
        int size = strlen(p);
        ptr = new char[size + 1];
        ptr[size]='\0';
        strcpy(ptr,p);
        cout<<"constructor!"<<endl;
      }
      ~Test(){
        delete[] ptr;
        cout<<"destructor"<<endl;
      }
    public:
     char* ptr=nullptr;
};


Test getTest(){
  Test t("123");
  return t;
}

int main(void){
  //block1
  const char* p = getTest().ptr;
  
  cout<<p<<endl;//这里的指针p已经是野指针啦。
  /*block1 的输出
    constructor!
    destructor
    123
  */
 
  //block2
  Test x = getTest();
  cout<<x.ptr<<endl;
  /*blcok2 的输出
  constructor!
  123
  destructor
   */
  return 0;
}

getTest函数执行过程:(这里略过c++的返回值优化问题)

先定义一个对象t,返回t,返回的时候会拷贝一份t,记为临时变量t1,

因为t是函数内定义的变量。生存周期为函数体内。

而t1的生存周期在getTest().ptr这行代码执行完就结束了。

那么p就指向了一个已经析构的对象内部变量。自然就变成了野指针。

虽然第一段代码块输出没错,有可能是编译器的实现不一样,但代码是错误的

第二段代码没有问题,并且编译器对这段代码做了返回值优化

返回值优化参考链接