0

just trying to wrap my head around how I go about deallocating memory of new objects which are passed as arguments.

Say I have a Link class defined like this:

class Link{
public:
 Link(const std::string& value, Link* previous = nullptr, Link* successor = nullptr) : _value{ value }, _previous{ previous }, _successor{ successor }{}
 Link* Insert(Link* new_link);
 Link* getPreviousLink() const{ return _previous; }
 Link* getSuccessorLink() const{ return _successor; }
 std::string _value;
private:
 Link* _previous;
 Link* _successor;
};

And then I have Link* Insert(Link*) defined like so:

Link* Link::Insert(Link* new_link){
 if(!new_link){ return this; }
 if(!this){ return new_link; }
 new_link->_successor = this;
 if(_previous){ _previous->_successor = new_link; }
 new_link->_previous = _previous;
 _previous = new_link;
 return new_link;
}

And then in my main(), I do the following:

int main(){
 Link* Cars = new Link("Ford");
 Cars = Cars->Insert(new Link("Ferrari"));
 Cars = Cars->Insert(new Link("Hummer"));
 Cars = Cars->Insert(new Link("Volvo"));
}

I've created a Link pointer called 'Cars' and allocated a new Link on the heap with a value of "Ford". I then assign my Cars pointer to a new Link returned from Insert(). Repeat this step 2 more times.

My question is, how do I delete or free the memory allocated when I pass the new Link objects as arguments? Do I do so in the destructor of Link? If I just delete my Cars pointer, it wouldn't deallocate the other Links.

asked May 15, 2018 at 0:13
14
  • 2
    if(!this){ return new_link; } means you invoked a method on a null pointer. Not a good idea. Not sure if it's flat-out Undefined Behaviour, but it happening is usually a sign of something in your code that requires a re-think. Commented May 15, 2018 at 0:17
  • 1
    if(!this){ return new_link; }is suspicious as it is UB to call a member function when this is nul. Commented May 15, 2018 at 0:17
  • If you're going to use new, you must decide which piece of code is responsible for deleting that data structure. Yes, you can do it in ~Link(), but then you must be sure you never call that destructor on a Link that has a static Link as a successor. Commented May 15, 2018 at 0:20
  • 2
    @user4581301 see stackoverflow.com/questions/2474018/… Commented May 15, 2018 at 0:21
  • 1
    Think about it. A->B, you try to delete A, A's dtor tries to delete B, B's dtor tries to delete A, A's (second) dtor tries to delete B; in principle this goes on forever, in practice after a few more rounds you overload the call stack and crash. I'm all in favor of implementing a doubly link list in order to learn pointercraft, but that means learning to spot these problems. Commented May 15, 2018 at 1:12

1 Answer 1

4

With smart pointer, ownership would be clear:

class Link : public std::enable_shared_from_this<Link> {
public:
 Link(const std::string& value) : _value{ value } {}
 std::shared_ptr<Link> Insert(std::shared_ptr<Link> new_link);
 std::shared_ptr<Link> getPreviousLink() const{ return _previous.lock(); }
 std::shared_ptr<Link> getSuccessorLink() const{ return _successor; }
 std::string _value;
private:
 std::weak_ptr<Link> _previous;
 std::shared_ptr<Link> _successor;
};
std::shared_ptr<Link> Link::Insert(std::shared_ptr<Link> new_link)
{
 if (!new_link){ return shared_from_this(); }
 new_link->_successor = shared_from_this();
 auto prev = _previous.lock();
 if (prev) { prev->_successor = new_link; }
 new_link->_previous = prev;
 _previous = new_link;
 return new_link;
}
int main(){
 auto Cars = std::make_shared<Link>("Ford");
 Cars = Cars->Insert(std::make_shared<Link>("Ferrari"));
 Cars = Cars->Insert(std::make_shared<Link>("Hummer"));
 Cars = Cars->Insert(std::make_shared<Link>("Volvo"));
}
answered May 15, 2018 at 0:28
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.