Mistake: using raw pointers when several parts of a structure share one dynamically allocated entity. A deque node may have multiple references, making deletion the developer’s responsibility at every possible exit and exception path. Missing one deletion leaks resources; duplicating ownership logic makes the data structure harder to understand and maintain. section 2.9
Listing 2.17 A deque using raw pointers
class Node {
public:
Node(int value) : data(value), prev(NULL), next(NULL) {}
int data;
Node* prev;
Node* next;
};
class Deque {
private:
Node* front;
Node* back;
public:
Deque() : front(NULL), back(NULL) {}
~Deque() { #1
while (front != NULL) {
Node* temp = front;
front = front->next;
delete temp;
}
}
void push_front(int value) {
Node* newNode = new Node(value);
if (front == NULL)
front = back = newNode;
else {
newNode->next = front;
front->prev = newNode;
front = newNode;
}
}
void push_back(int value) {
Node* newNode = new Node(value);
if (back == NULL)
front = back = newNode;
else {
newNode->prev = back;
back->next = newNode;
back = newNode;
}
}
void pop_front() {
if (front != NULL) {
Node* temp = front; #2
front = front->next;
if (front != NULL)
front->prev = NULL;
else
back = NULL;
delete temp; #3
}
}
void pop_back() {
if (back != NULL) {
Node* temp = back; #4
back = back->prev;
if (back != NULL)
back->next = NULL;
else
front = NULL;
delete temp; #5
}
}
};
int main() {
Deque deque;
deque.push_front(3);
deque.pop_front();
return 0;
}
The raw-pointer deque makes ownership visible through manual destructor logic and repeated delete decisions. Use it to locate the maintenance and exception-safety risks that shared ownership removes. section 2.9
Replace manual node ownership
Declare links and deque endpoints as std::shared_ptr<Node>, initialize empty pointers with nullptr, and create nodes with std::make_shared<Node>(value). Assigning the same node to front, back, prev, or next allows shared ownership while RAII releases the resource when its owners are gone. The deque no longer needs a destructor that walks the list and deletes nodes. section 2.9
Listing 2.18 A deque using shared pointers
class Node {
public:
Node(int value) : data(value) {}
int data;
std::shared_ptr<Node> prev; #1
std::shared_ptr<Node> next; #2
};
class Deque {
private:
std::shared_ptr<Node> front;
std::shared_ptr<Node> back;
public:
Deque() : front(nullptr), back(nullptr) {} #3
void push_front(int value) {
std::shared_ptr<Node> newNode = std::make_shared<Node>(value);
if (front == nullptr)
front = back = newNode;
else {
newNode->next = front;
front->prev = newNode;
front = newNode;
}
}
void push_back(int value) {
std::shared_ptr<Node> newNode = std::make_shared<Node>(value);
if (back == nullptr)
front = back = newNode;
else {
newNode->prev = back;
back->next = newNode;
back = newNode;
}
}
void pop_front() {
if (front != nullptr) {
front = front->next;
if (front != nullptr)
front->prev = nullptr;
else
back = nullptr;
} #B
}
void pop_back() {
if (back != nullptr) {
back = back->prev;
if (back != nullptr)
back->next = nullptr;
else
front = nullptr;
} #4
}
};
int main() {
Deque deque;
deque.push_front(3);
deque.pop_front();
return 0;
}
The corrected deque shows the smallest practical migration: replace node pointer members and endpoints, use nullptr, and construct nodes with make_shared. section 2.9
Prefer std::shared_ptr when two or more references share a resource, and prefer std::make_shared over explicit new whenever possible. If modern C++ is unavailable, Boost supplies shared-pointer alternatives; avoid deprecated std::auto_ptr. section 2.9 section 10.6

