I'm trying to implement a Deque using smart pointers. However, I noticed that at the end of the program the Nodes of the Deque are not destructed properly.
Here is the code:
#include<iostream>
#include<memory>
class Node
{
int value;
std::shared_ptr<Node> next = nullptr;
std::shared_ptr<Node> prev = nullptr;
public:
Node() = default;
Node(int val): value(val) {}
~Node()
{
std::cout << "Destructor of node: " << value << std::endl;
}
friend class Deque;
};
class Deque
{
using pointer = std::shared_ptr<Node>;
pointer head = nullptr; // pointer to the first element of the queue
pointer tail = nullptr; // pointer to the last element of the queue
public:
Deque() = default;
~Deque(){ std::cout << "Dequeue destructor" << std::endl; }
bool is_empty()
{
if (head == nullptr && tail == nullptr )
return true;
else
return false;
}
void push_back(const pointer& val)
{
if (is_empty())
{
head = val;
tail = val;
}
else
{
val->prev = tail;
tail->next = val;
tail = val;
}
}
};
int main()
{
Deque DEQ;
auto node1 = std::make_shared< Node >(1);
auto node2 = std::make_shared< Node >(2);
auto node3 = std::make_shared< Node >(3);
DEQ.push_back(node1);
DEQ.push_back(node2);
std::cout << "Use count node1 = " << node1.use_count() << std::endl;
std::cout << "Use count node2 = " << node2.use_count() << std::endl;
std::cout << "Use count node3 = " << node3.use_count() << std::endl;
return 0;
}
The output is the following:
Use count node1 = 3
Use count node2 = 3
Use count node3 = 1
Destructor of node: 3
Dequeue destructor
when I push the node1
and node2
into the Deque, they are not destructed at the end of the program, while node3
is correctly destructed.
I assume the problem is that the reference count of node1
and node2
is equal to 3. Do you know how I can change my implementation in order to solve this problem? Thanks.
I assume the problem is that the reference count of node1 and node2 is equal to 3.
Your assumption is correct. Shared pointers do not destroy the pointed object until ref count drops to zero.
Do you know how I can change my implementation in order to solve this problem?
Don't have cycles in your ownership graph. You could for example use owning smart pointers in one direction of your list, and non-owning pointers (perhaps weak pointers) in the other direction.