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