Fix Memory Leak and Logic Bugs in Advanced Custom Smart Pointer Implementation
You are given a custom smart pointer class in C++ designed to manage dynamic memory with reference counting. The implementation contains subtle memory leaks and logic bugs causing incorrect reference counting and dangling pointers. Your task is to identify and fix these bugs to ensure safe and correct memory management.
Challenge prompt
The provided CustomSmartPointer class aims to replicate basic shared pointer functionality using reference counting. However, it currently leaks memory, mishandles copy and assignment, and may cause double deletes or use-after-frees. Your challenge is to spot all logical errors and fix them so that the pointer properly manages dynamic memory without leaks or crashes. The class interface should remain unchanged and support copy construction, assignment, and destruction correctly.
Guidance
- • Review the reference counting logic carefully, especially in copy constructor and assignment operator.
- • Check that resources are freed exactly once when the last owner releases them.
- • Ensure all pointer updates and reference count increments/decrements happen safely and in the right order.
Hints
- • The assignment operator should handle self-assignment safely and decrement the old pointer's ref count correctly.
- • The destructor must only delete the managed object if no other references remain.
- • Consider edge cases like assigning the smart pointer to itself or resetting pointers to nullptr.
Starter code
template<typename T>
class CustomSmartPointer {
private:
T* ptr;
int* refCount;
public:
CustomSmartPointer(T* p = nullptr) : ptr(p), refCount(new int(1)) {}
CustomSmartPointer(const CustomSmartPointer& other) {
ptr = other.ptr;
refCount = other.refCount;
(*refCount)++;
}
CustomSmartPointer& operator=(const CustomSmartPointer& other) {
if (this != &other) {
ptr = other.ptr;
refCount = other.refCount;
(*refCount)++;
}
return *this;
}
~CustomSmartPointer() {
(*refCount)--;
if (*refCount == 0) {
delete ptr;
delete refCount;
}
}
T& operator*() { return *ptr; }
T* operator->() { return ptr; }
};Expected output
All dynamically allocated objects are properly deleted without memory leaks or crashes during sample usage and testing.
Core concepts
Challenge a Friend
Send this duel to someone else and see if they can solve it.