C++ programming careful pointer is deleted twice

  • 2020-04-02 02:26:33
  • OfStack

In C++ classes, pass-through calls are sometimes used (that is, using object entities as arguments), so be careful! This is especially true if the object you are passing values to has a longer life cycle than a temporary object (life cycle segment). Take a look at the following:


#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{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;
}

The result of the above execution is that the program crashes. The reason is:

Print(Text STR) does not make a depth copy of STR when copying the structure of STR. When Print exits, since it is a temporary object (constructed at the beginning of the function), STR is destructed, so there is no problem. But when we go back to main and then exit main, we destruct t again, but the contents of STR inside t have been destroyed. A memory error occurred because a memory space was destroyed twice.

The solution is as follows:

Copy before rewriting. Like the following version, different situations should be adjusted appropriately:


#include <iostream>
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;
}

It is recommended not to use pass-through calls. Just like the following Print version:


void Print(Text &str)
{
cout << str.GetText() << endl;
}

Unless all members of the object read non-pointer memory content, use the usage mentioned earlier in this article with caution.


Related articles: