0

I'm taking a C++ class and I'm having a hard time understanding when do I need to delete a pointer. From my previous understanding, we need to de-allocate memory whenever a pointer that was created with new is not used anymore. On the other hand, a pointer that is assigned using a reference to another variable doesn't need it.

In the case of the setter for an instance variable of a class, do we need it? There is no way to know if the pointer that is passed to the setter has been created with "new" or not.

Test.cpp

int main(){
string name = "john";
string address = "11 blv. hello";
string tel = "514-999-9999";
Date d(1,1,1);

Customer bob(name, address, tel, &d);

bob.printInfo();
Date d2(2,2,2);

bob.setDob(&d2); //Could also be new Date(2,2,2)

bob.printInfo();

return 0;
}

The setter in Customer.cpp:

void Customer::setDob(Date *d){

//delete(dob); Do I need to put it or not? 
Customer::dob = d;
}
Etienne Berube
  • 547
  • 1
  • 7
  • 21
  • As someone who is still learning, you would probably want to use `setDob(Date d)` -- that is, no pointer -- to solve the exact issue with pointers that you describe in your question. Having your `Customer` class manage pointers to simple data may prove more trouble than it's worth. – Drew Dormann Jan 21 '18 at 21:44
  • With raw pointers you can't tell who owns it (if you need to delete it or not) which is why their use is discouraged. It is down to the documentation to tell the person using your class that they need to create the object using `new`. Better to use a smart pointer like a `std::unique_ptr` which makes it clear who owns the pointer and it gets deleted automatically. – Galik Jan 21 '18 at 21:45
  • At first, I did find pointers to be more efficient (I come from a Java background where every object is a pointer and there's a GC). The idea of calling a copy constructor each time did discourage me to use `setDob(Date d)`. I did use `setDOB(Date &d)` for a while but it becomes messy with `const`. – Etienne Berube Jan 21 '18 at 21:51
  • 1
    If you're coming from Java, you need to learn about value semantics and const correctness. Without that C++ will be a real pain, and not really worth it. – juanchopanza Jan 21 '18 at 21:55
  • Be careful with your assumption: "a pointer that is assigned using a reference to another variable doesn't need it". This is missing a key point: "a pointer that is assigned using a reference to a variable **on the stack** doesn't need it". Why? Because the C++ language will "delete" that variable for you when you exit the scope it was declared in (at the next closing `}`). Check out: https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap. – Brian Rodriguez Jan 21 '18 at 21:55
  • Eve if the pointer points to a variable created dynamically (i.e. with `new`), *that does not mean that the setter can assume that the calling code will not need the variable any more.* In a situation like this, I think the calling code passes the pointer, but it cannot pass the responsibility. – Beta Jan 21 '18 at 22:06
  • One thing to consider about passing values and pointers is that a `Date` object is likely to be rather small. It may even be smaller than a pointer. So passing a pointer is unlikely to be faster than passing a `Date` by value. But it may be slower to access because you have to indirect through the pointer. – Galik Jan 21 '18 at 22:28

1 Answers1

1

I'm having a hard time understanding when do I need to delete a pointer.

From my previous understanding, we need to de-allocate memory whenever a pointer that was created with new is not used anymore.

Your understanding here is pretty much spot on. You need to delete a pointer exactly whenever you've allocated an object with a new expression, and you don't use it anymore.

Conversely, you must not delete anything that wasn't allocated with a new expression, and you must not delete anything that is still being used. Nor may you delete anything that has already been deleted.

On the other hand, a pointer that is assigned using a reference to another variable doesn't need it.

Correct. Not only isn't deleting a pointer to a variable object not needed, it is in fact something that musn't be done. Variables are not created with a new expression. As such, they must not be deleted.

In the case of the setter for an instance variable of a class, do we need it?

It depends on how that object was created. If it was created with new and if you're not going to delete it elsewhere, then you must delete it here. If the object was not created with new, or if you do delete it elsewhere, then you must not delete it here.

There is no way to know if the pointer that is passed to the setter has been created with "new" or not.

In that case, you must not delete the pointer here. Otherwise you could be deleting something that must not be deleted. In other words, the function must not take ownership of that pointer.

If the pointed object is dynamic, then it has to be deleted somewhere else:

// For demonstrative purpose only.
// It's never a good idea to use owning bare pointers.
// Use smart pointers.
auto ptr = new Date(2,2,2);
Date d2(2,2,2);
{
    Customer bob(name, address, tel, &d);
    bob.setDob(&d2); // OK
    bob.setDob(ptr); // OK
    bob.setDob(new Date(2,2,2)); // Not OK; would leak memory
}
delete ptr;

I see no good reason why a Customer class would point to an external Date object as the dob (date of birth?). That seems something that should be a sub-object of Customer.

Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326