cppadvanced15 minutes

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

C++ pointersreference countingcopy constructorassignment operatormemory management

Challenge a Friend

Send this duel to someone else and see if they can solve it.