0

I'm trying to understand copy assignment in C++. I know it's best to use copy-and-swap idiom for this operator. But for this simple class without consider the Exception safety, when will *ps = *(h.ps); fail? could you please provide some examples where this can go wrong? thanks

class HasPtr {
public:
  HasPtr(std::string const & s = std::string()):
    ps(new std::string(s)), i(0) {}

  HasPtr(HasPtr const & h):
    ps(new std::string(*(h.ps))), i(h.i) {}

  HasPtr & operator = (HasPtr const & h) {
    *ps = *(h.ps);
    i = h.i;
    return *this;
  }

  ~HasPtr(){ delete ps;}

private:
  std::string * ps;
  int i;
};

I've tried to use GPT, it says there will be a memory leak, but I just can't see it

9
  • "I've tried to use GPT, it says there will be a memory leak, but I just can't see it": It is wrong. There is no leak or exception safety issue in the code that you are showing. It is pointless to ask ChatGPT such questions. That said, it is only correct because you assign the string first. That can throw and if it throws, you probably don't want to have your object in a half-assigned state. On the other hand i = h.i can't throw, so that is not an issue in this specific case. Commented Aug 19 at 4:25
  • 4
    That said, it is completely pointless to hold a pointer to an owned std::string. That should simply be std::string instead of std::string* and then you don't need any of your copy overloads, destructor or new. Follow the rule-of-zero whenever possible. If necessary, because you can't store the object directly by-value for whatever reason, use std::unique_ptr, not raw pointers and new, to achieve this. Commented Aug 19 at 4:27
  • new std::string(s) ehr... no. You will NOT know who owns the pointer. In C++ avoid using "owning raw pointers" at all costs. Use std::unique_ptr or std::shared_ptr depending on the ownership model you need. With your "design" you can easily run into double free issues, you will have to implement your move and copy constructors to do what is right (e.g. move ownership of ps or share it) Commented Aug 19 at 4:36
  • ChatGPT doesn't know (the correct details of) C++, so never rely on that. Commented Aug 19 at 4:38
  • Where can *ps = *(h.ps); fail? Out of Memory exception allocating more storage for *ps, but since nothing else in the receiving HasPtr has been changed at that point, no harm is done to it (but only because string itself has a strong exception guarantee). As my fellow anonymous user points out, if you moved the i = h.i; up a line so that i could have changed before the exception blew up, that would be a problem. This class is too friendly. To get a better example, where there is a lot of room for fail, write an assignment operator for a roll-your-own linked list class. Commented Aug 19 at 4:55

0

Browse other questions tagged or ask your own question.