← Back to list

Understanding Double Deletion, Wild Pointers, and Dangling Pointers in C++

Manual memory management gives C++ its power — but also its sharpest edges. If you mismanage ownership, you won’t simply get a bug; you’ll…

Seulgie Han · 2025-12-09 13:05 · 0 claps · 2.4 min read
#cplusplus #raii #dangling-pointer
Open on Medium ↗
Wiki topics: BIZ · Business Strategy

Understanding Double Deletion, Wild Pointers, and Dangling Pointers in C++

Manual memory management gives C++ its power — but also its sharpest edges. If you mismanage ownership, you won’t simply get a bug; you’ll get crashes, corrupted memory, or behavior so unpredictable that debugging becomes a nightmare. In this post, we’ll walk through two classic mistakes:

  • Double Deletion
  • Wild & Dangling Pointers

We’ll examine why they occur, how to fix them, and how to build safe mental models for memory ownership.

Double Deletion: When Ownership Goes Wrong

A double deletion happens when the same dynamically allocated block of memory is freed more than once. Here’s a simple — but dangerous — example:

#include <iostream>

class MyResource {
public:
    int* data;
    MyResource(int val) {
        data = new int(val);
        std::cout << "Resource created at address " << data << std::endl;
    }
    ~MyResource() {
        std::cout << "Resource destroyed, deleting data at " << data << std::endl;
        delete data;
    }
};

int main() {
    MyResource* ptr1 = new MyResource(10);
    MyResource* ptr2 = ptr1; // ptr2 now points to the same object as ptr1

    // PROBLEM: deleting the same object twice
    delete ptr1;
    delete ptr2;

    return 0;
}

Why this crashes? ptr1 and ptr2 point to the same MyResource instance. Deleting ptr1 destroys the object and frees data. Deleting ptr2 attempts to destroy an object that no longer exists -> undefined behavior. This is a pure ownership violation.

✅ Fix: Ensure Only One Owner

You can fix this in several safe ways:

Option A: Avoid duplicating raw ownership

Correct and simplest fix:

int main() {
    MyResource* ptr1 = new MyResource(10);

    delete ptr1;  // delete only once

    return 0;
}

Option B: Use std::unique_ptr

The real modern C++ solution:

#include <memory>

int main() {
    std::unique_ptr<MyResource> ptr1 = std::make_unique<MyResource>(10);

    // Ownership cannot be duplicated accidentally.
}

Wild and Dangling Pointers

Wild and dangling pointers are another category of dangerous memory bugs.

  • Wild pointer: An uninitialized pointer pointing to an unknown location.
  • Dangling pointer: A pointer that used to point to valid memory but that memory has been freed.

Consider the following code:

#include <iostream>

int* create_integer() {
    int* some_int; // Wild pointer
    *some_int = 100;
    return some_int;
}

some_int is uninitialized — it could point anywhere. Writing to *some_int corrupts arbitrary memory. Now the main function:

int main() {
    int* my_ptr = new int(50);
    std::cout << "Value before delete: " << *my_ptr << std::endl;

    delete my_ptr;   // memory freed
    std::cout << "Value after delete: " << *my_ptr << std::endl; // Dangling pointer

    int* ptr_from_function = create_integer();
    std::cout << "Value from function: " << *ptr_from_function << std::endl;

    delete ptr_from_function;
    return 0;
}

❗ What’s wrong here?

  1. my_ptr is dangling after delete.
  2. create_integer() returns a wild pointer. The program crashes before the dangling pointer problem even matters.

✅ Fixing the Wild and Dangling Pointer Bugs

Fix 1: Initialize the pointer properly

int* create_integer() {
    int* some_int = new int(100); // allocate properly
    return some_int;
}

Fix 2: Avoid using my_ptr after deleting

delete my_ptr;
my_ptr = nullptr; // defensive habit

Fixed Program

#include <iostream>

int* create_integer() {
    int* some_int = new int(100);  // FIX: allocate properly
    return some_int;
}

int main() {
    int* my_ptr = new int(50);
    std::cout << "Value before delete: " << *my_ptr << std::endl;

    delete my_ptr;
    my_ptr = nullptr;  // FIX: avoid dangling pointer use

    int* ptr_from_function = create_integer();
    std::cout << "Value from function: " << *ptr_from_function << std::endl;

    delete ptr_from_function;

    return 0;
}

Key Takeaways

  • A pointer is not memory; it is merely a reference to memory. Copying a raw pointer does not copy ownership.
  • Deleting memory twice is a catastrophic ownership violation.
  • Uninitialized pointers (wild pointers) are as dangerous as loaded guns.
  • A pointer that outlives its memory (dangling pointer) invites undefined behavior.
  • The best long-term solution is to embrace RAII and smart pointers like std::unique_ptr and std::shared_ptr.

메타데이터
post_id
e43bbaea2cb3
slug
understanding-double-deletion-wild-pointers-and-dangling-pointers-in-c-e43bbaea2cb3
url
https://medium.com/@su-paris/understanding-double-deletion-wild-pointers-and-dangling-pointers-in-c-e43bbaea2cb3
canonical_url
https://medium.com/@su-paris/understanding-double-deletion-wild-pointers-and-dangling-pointers-in-c-e43bbaea2cb3
author_url
https://medium.com/@su-paris
status
ok
fetched_at
2026-07-07 00:45:30