Hard15 minC++ Fundamentals
UpdatedAug 4, 2026
Edit

Smart Pointer Ownership

CONCEPTS:C++ Smart Pointers

Question Variations

  • "When should you use `unique_ptr` versus `shared_ptr`?"
  • "What problem does `weak_ptr` solve?"
  • "Why is `shared_ptr` not a general replacement for ownership design?"
  • "How do smart pointers relate to raw non-owning pointers?"

Why This Is Asked

Smart pointers make heap ownership explicit in modern C++. Interviewers use this question to see whether you choose exclusive ownership by default, understand the cost and lifetime model of shared ownership, and prevent reference cycles.

Key Concepts

  • std::unique_ptr has one owner and transfers ownership by move.
  • std::shared_ptr uses a reference-counted control block for shared ownership.
  • std::weak_ptr observes a shared_ptr-managed object without keeping it alive.
  • Prefer std::make_unique and std::make_shared for exception-safe construction.

Question Variations

  • “When should you use unique_ptr versus shared_ptr?”
  • “What problem does weak_ptr solve?”
  • “Why is shared_ptr not a general replacement for ownership design?”
  • “How do smart pointers relate to raw non-owning pointers?”

Answers by Technology

+ Add Variant
C++Improve this answer ✏️

Expected Answer (C++23)

Use std::unique_ptr<T> for exclusive heap ownership; it is lightweight and communicates that one component controls lifetime. Use std::shared_ptr<T> only when ownership genuinely must be shared and no single owner can be identified. std::weak_ptr<T> breaks cycles and lets code check whether a shared object still exists without extending its lifetime.

Raw pointers and references can still be useful as non-owning views, but their lifetime must be guaranteed by another owner. Prefer factory helpers to avoid a window where a raw allocation could leak if later construction throws.

#include <memory>
#include <string>

struct Connection {
    explicit Connection(std::string name) : name(std::move(name)) {}
    std::string name;
};

int main() {
    auto connection = std::make_unique<Connection>("primary");
    // Ownership can be transferred, not copied.
    auto worker_connection = std::move(connection);
}

Why It Matters

Explicit ownership avoids leaks and double deletion while making APIs easier to reason about. Unnecessary shared ownership creates hidden lifetime coupling, atomic-counting overhead, and cycles that leak memory.

Common Mistakes

  • Using shared_ptr by default: It hides ownership responsibility and costs more than exclusive ownership.
  • Creating two shared_ptr objects from the same raw pointer: Each control block tries to delete the object, causing double deletion.
  • Using only shared_ptr for two-way relationships: A cycle keeps both objects alive; one direction usually needs weak_ptr.

Follow-up Questions

  • What does weak_ptr::lock() return? (Answer: A shared_ptr if the object is still alive, otherwise an empty shared_ptr.)
  • Why use make_unique? (Answer: It is concise and exception-safe, and clearly constructs one owning pointer.)