<% dim ModuleName,InfoID,ChannelShortName,CorrelativeArticle,InstallDir,ChannelDir,Keyword,PageTitle,ArticleIntro,Articlecontent Keyword=stripHTML("指针,delete") PageTitle=stripHTML("小心指针被delete两次") ArticleIntro=stripHTML("") Articlecontent=stripHTML("小心指针被delete两次  C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生…") ModuleName = stripHTML("programme") InfoID = stripHTML("117228") ChannelShortName=stripHTML("编程") InstallDir=stripHTML("http://www.77169.com/") ChannelDir=stripHTML("programme") %> 小心指针被delete两次 - 华盟网 - http://www.77169.com
您现在的位置: 华盟网 >> 编程 >> C语言 >> 正文

小心指针被delete两次

2014/7/31 作者:不详 来源: 华盟收集
导读 <% if len(ArticleIntro)<3 then Response.Write Articlecontent 'Response.Write "Articlecontent" else Response.Write ArticleIntro 'Response.Write "ArticleIntro" end if %>

  小心指针被delete两次

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

  #include

  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{return str;}

  ~Text()

  {

  cout 《 "~Text Destruction" 《 endl;

  delete [] str;

  cout 《 "~Text Over" 《 endl;

  }

  };

  void Print(Text str)

  {

  cout 《 str.GetText() 《 endl;

  }

  int main()

  {

  Text t;

  t.SetText("abc");

  Print(t);

  return 1;

  }

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

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

  解决方法:

  重写浅拷贝。像一下版本,不同的情况要作出适当的调整:

  #include

  using namespace std;

  class Text

  {

  private:

  char * str;

  public:

  Text(){str = new char[20];::memset(str,0,20);}

  Text(Text &t)

  {

  str = new char[20];

  strcpy(str,t.GetText());

  }

  void SetText(char * str)

  {

  strcpy(this->str,str);

  }

  char * GetText() const{return str;}

  ~Text()

  {

  cout 《 "~Text Destruction" 《 endl;

  delete [] str;

  cout 《 "~Text Over" 《 endl;

  }

  };

  void Print(Text str)

  {

  cout 《 str.GetText() 《 endl;

  }

  int main()

  {

  Text t;

  t.SetText("abc");

  Print(t);

  return 1;

  }

  (推荐)不使用传值调用。就像下面书写如下Print版本:

  void Print(Text &str)

  {

  cout 《 str.GetText() 《 endl;

  }

  除非对象内所有的成员读属非指针内存内容,那么谨慎使用文章前面的用法。



  • 上一篇编程:

  • 下一篇编程: