大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C++技巧 > 小心指针被delete两次

小心指针被delete两次

关键词:指针delete  阅读(584) 赞(15)

[摘要]本文是对小心指针被delete两次的讲解,对学习C++编程技术有所帮助,与大家分享。

C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生命周期段)的时候。来看看下面的情况:

#include <iostream>
using namespace std;
class Text
{
private:
char* str;
public:
Text(){str = new char[20];::memset(str,0,20);}
void SetText(char* str)
{
strcpy(this->str,str);
}
char* GetText() const{returnstr;}
~Text()
{
cout << "~Text Destruction"<< endl;
delete[] str;
cout << "~Text Over"<< endl;
}
};
void Print(Text str)
{
cout << str.GetText() << endl;
}
intmain()
{
Text t;
t.SetText("abc");
Print(t);
return1;
}

上面执行的结果程序崩溃了。原因:

Print(Text str)在对str进行复制构造的时候,没有进行深度拷贝;当 Print退出的时候,因为是临时对象(函数初始时构造),对str进行析构,此时还没有任何破绽;但回到main,继而退出main 的时候,又对t进行析构,但此时t内的str中的内容已经被销毁。由于对一内存空间实施了两次销毁,于是出现内存出错。

解决方法:

    1. 重写浅拷贝。像一下版本,不同的情况要作出适当的调整:
      #include <iostream>
      usingnamespacestd;
      classText
      {
      private:
      char* str;
      public:
      Text(){str = newchar[20];::memset(str,0,20);}
      Text(Text &t)
      {
      str = newchar[20];
      strcpy(str,t.GetText());
      }
      voidSetText(char* str)
      {
      strcpy(this->str,str);
      }
      char* GetText() const{returnstr;}
      ~Text()
      {
      cout << "~Text Destruction"<< endl;
      delete[] str;
      cout << "~Text Over"<< endl;
      }
      };
      voidPrint(Text str)
      {
      cout << str.GetText() << endl;
      }
      intmain()
      {
      Text t;
      t.SetText("abc");
      Print(t);
      return1;
      }
    2. (推荐)不使用传值调用。就像下面书写如下Print版本:
      voidPrint(Text &str)
      {
      cout << str.GetText() << endl;
      }
    3. 除非对象内所有的成员读属非指针内存内容,那么谨慎使用文章前面的用法。


相关评论