Home > Blockchain >  C - Should you delete allocated memory in the copy assignment operator of a class that uses raw po
C - Should you delete allocated memory in the copy assignment operator of a class that uses raw po

Time:07-30

I am still somewhat new at c , and I am a little confused about this.

Say we have struct struct_x that uses raw pointers as attributes. Should the raw pointers then be deleted in the copy assignment operator, when they are already allocated? Or should you just assign the new pointee to the pointer? (I am aware that it is advised to use smart/unique/shared pointers).

Code example:

struct struct_x {
public:

    // Some attributes.
    char*       m_arr           nullptr;
    size_t*     m_len =         nullptr;
    size_t*     m_alloc_len =   nullptr;

    // Default constructor.
    struct_x() {
        m_len =         new size_t(0);
        m_alloc_len =   new size_t(0);
    }

    // Copy constructor.
    // Treat "struct_x" as a unique pointer for this example.
    struct_x(const struct_x& x) {

        // Assign.
        m_arr = new char[*x.m_alloc_len   1];
        memcpy(m_arr, x.m_arr,*x.m_len);
        m_len = new size_t(*x.m_len);
        m_alloc_len = new size_t(*x.m_alloc_len);

    }

    // Copy assignment operator.
    void operator =(const struct_x& x) {

        //
        //
        // OVER HERE
        //
        // Should the pointers be deleted when they are already allocated?
        // Like:
        if (m_arr != nullptr) { delete[] m_arr; }
        if (m_len != nullptr) { delete m_len; }
        if (m_alloc_len != nullptr) { delete m_alloc_len; }
        // Or not?

        // Assign.
        ...
    }

}

CodePudding user response:

If you are implementing a string-like class as an exercise, then m_len and m_alloc_len should not be pointers at all. Only m_arr should be a pointer. If you are not doing an exercise, you should be using std::string or perhaps std::vector<char>.

Having said that...

It is perfectly fine and necessary to delete owning raw pointers in assignment operators of resource-managing classes.

There is a caveat though. The assignment operator should be protected against self-assignment. If you do

my_object = my_object;

then without such protection your program will access deleted memory area. You want this:

void operator =(const struct_x& x) {
  if (this != &x) {
    // contents of your assignment operator
  }
}

my_object = my_object is an unlikely assignment to appear in a program, but such things can and do happen, especially if there is indirection involved. Say when doing a[i] = a[j], it is perfectly reasonable to have i == j.

There are other (better) ways to protect against self-assignment. You will encounter them in due course. You probably need to learn about move semantics first.before

  • Related