Reputation: 632
I need to create an + operator for my class, I did it like this:
class CDoubleString{
public:
string textA="";
string textB="";
CDoubleString(string x,string y) : textA(x),textB(y){}
CDoubleString & operator + (const CDoubleString & y){
CDoubleString * n=new CDoubleString(textA,textB);
n->textA+=y.textA;
n->textB+=y.textB;
delete n;
return *n;
}
}
It seems that it is working as expected, but I see that there is a problem with freeing the memory. In the moment I returned it, it already may be something else. So it is undefined behaviour, am I correct?
How to avoid that?
Upvotes: 0
Views: 56
Reputation:
So it is undefined behaviour, am I correct?
Yes, but not quite for the reason you think. You're returning a reference to an already-deleted object, and that's invalid and has undefined behaviour. But the "it already may be something else" applies to the caller, because it's the caller that would actually end up reading from that dead reference, and that's something that could cause problems even if you were to delay the deletion of the object: you might still not delay it enough.
How to avoid that?
Returning by value is probably easiest.
CDoubleString operator + (const CDoubleString & y){
CDoubleString n(textA,textB);
n.textA+=y.textA;
n.textB+=y.textB;
return n;
}
Upvotes: 1
Reputation: 1
So it is undefined behaviour, am I correct?
Yes.
How to avoid that?
There are several ways.
Return by value
CDoubleString operator + (const CDoubleString & y){
CDoubleString n(textA,textB);
n.textA+=y.textA;
n.textB+=y.textB;
return n;
}
Return a std::unique_ptr
std::unique_ptr<CDoubleString> operator + (const CDoubleString & y){
std::unique_ptr<CDoubleString> n = std::make_unique<CDoubleString>(textA,textB);
n->textA+=y.textA;
n->textB+=y.textB;
return n;
}
I'd prefer the 1st variant for your case. You can rely on RVO and copyelistion for most modern compilers, so you don't need to worry about additional copies made.
Upvotes: 3