PracHub
QuestionsCoachesLearningGuidesInterview Prep
|Home/Software Engineering Fundamentals/Sig

Find and Fix C++ Ownership Bugs: Double Free, Shallow Copy, and Object Slicing

Last updated: Jul 1, 2026

Quick Overview

This question evaluates a candidate's understanding of C++ object lifetime, copy semantics, and polymorphism. It tests the ability to spot shallow-copy bugs like double free and object slicing, and to reason about the Rule of Three/Five, commonly asked to assess practical memory-management and design skill in software engineering interviews.

  • medium
  • Sig
  • Software Engineering Fundamentals
  • Software Engineer

Find and Fix C++ Ownership Bugs: Double Free, Shallow Copy, and Object Slicing

Company: Sig

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

You are given C++ code that compiles and "works" in simple cases but is subtly broken. Read it, identify every bug, explain the underlying root cause, and rewrite it correctly. **Scenario A — a resource-owning class.** `Buffer` owns a heap allocation through a raw pointer and relies on the compiler to generate its copy operations: ```cpp class Buffer { public: explicit Buffer(std::size_t n) : size_(n), data_(new int[n]) {} ~Buffer() { delete[] data_; } int& at(std::size_t i) { return data_[i]; } std::size_t size() const { return size_; } private: std::size_t size_; int* data_; }; void use_a() { Buffer a(10); Buffer b = a; // (1) copy-construct b from a Buffer c(5); c = a; // (2) copy-assign a into c } // (3) a, b, c all destruct here ``` **Scenario B — a polymorphic type stored by value.** `Shape` is a base class; concrete shapes derive from it. They are stored and copied through a base-typed container: ```cpp struct Shape { virtual double area() const { return 0.0; } }; struct Circle : Shape { double r; explicit Circle(double r) : r(r) {} double area() const override { return 3.141592653589793 * r * r; } }; void use_b(std::vector<Shape>& shapes) { shapes.push_back(Circle(2.0)); // store a circle double a = shapes.back().area(); // expect ~12.566... } ``` For each scenario, state exactly what goes wrong, why, and provide a corrected version. ```hint What to look at first For Scenario A, count how many times each `new[]` allocation gets passed to `delete[]`. If two `Buffer` objects end up holding the same `data_` pointer, whose destructor runs on it — and how many times? ``` ```hint Which functions did the author rely on? The author wrote a destructor but no copy constructor or copy assignment operator. For a class that owns a raw pointer, are the compiler-generated defaults correct? (Rule of Three / Rule of Five.) ``` ```hint Polymorphism by value In Scenario B, `std::vector<Shape>` stores `Shape` objects by value. What happens to the `Circle`-specific part of the object when it is copied into a `Shape`-sized slot? What do a virtual `clone()` and pointer/`unique_ptr` storage buy you? ``` ### Constraints & Assumptions - C++17, single-threaded. - `Buffer` is intended to have value semantics: copyable, with each copy independently owning its own buffer. - The polymorphic shapes are meant to be stored and later queried without losing their dynamic type. - Prefer standard idioms (RAII, Rule of Five, smart pointers) over manual reference counting. ### Clarifying Questions to Ask - Should `Buffer` be deep-copyable, move-only, or non-copyable? (That decides which special members to write or `=delete`.) - Is exception safety (a strong guarantee on assignment) in scope, or only ownership correctness? - For the shapes, do we own the objects (so we must clone and delete them) or merely reference objects owned elsewhere? - May I use `std::unique_ptr`/`std::shared_ptr`, or should the fix be raw-pointer-only to demonstrate the Rule of Five explicitly? ### What a Strong Answer Covers ```premium-lock What a Strong Answer Covers ``` ### Follow-up Questions - How does copy-and-swap deliver the strong exception guarantee, and what does it require of `swap` and the move constructor? - When would you make `Buffer` move-only (`=delete` the copies) instead of deep-copyable, and how would call sites change? - Why is deleting a derived object through a base pointer with a non-virtual destructor undefined behavior? - How would a `std::variant<Circle, Square, ...>` or another closed sum type compare to the `clone()`-based open polymorphism for storing heterogeneous shapes?

Quick Answer: This question evaluates a candidate's understanding of C++ object lifetime, copy semantics, and polymorphism. It tests the ability to spot shallow-copy bugs like double free and object slicing, and to reason about the Rule of Three/Five, commonly asked to assess practical memory-management and design skill in software engineering interviews.

Related Interview Questions

  • Implement a Simplified std::vector with Manual Memory Management - Sig (medium)
  • Trees and Binary Search Trees: Taxonomy, Invariant, and Traversal/Search - Sig (medium)
|Home/Software Engineering Fundamentals/Sig

Find and Fix C++ Ownership Bugs: Double Free, Shallow Copy, and Object Slicing

Sig logo
Sig
Jun 15, 2026, 12:00 AM
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

You are given C++ code that compiles and "works" in simple cases but is subtly broken. Read it, identify every bug, explain the underlying root cause, and rewrite it correctly.

Scenario A — a resource-owning class. Buffer owns a heap allocation through a raw pointer and relies on the compiler to generate its copy operations:

class Buffer {
public:
    explicit Buffer(std::size_t n) : size_(n), data_(new int[n]) {}
    ~Buffer() { delete[] data_; }

    int&        at(std::size_t i)       { return data_[i]; }
    std::size_t size() const            { return size_; }
private:
    std::size_t size_;
    int*        data_;
};

void use_a() {
    Buffer a(10);
    Buffer b = a;     // (1) copy-construct b from a
    Buffer c(5);
    c = a;            // (2) copy-assign a into c
}                     // (3) a, b, c all destruct here

Scenario B — a polymorphic type stored by value. Shape is a base class; concrete shapes derive from it. They are stored and copied through a base-typed container:

struct Shape {
    virtual double area() const { return 0.0; }
};
struct Circle : Shape {
    double r;
    explicit Circle(double r) : r(r) {}
    double area() const override { return 3.141592653589793 * r * r; }
};

void use_b(std::vector<Shape>& shapes) {
    shapes.push_back(Circle(2.0));   // store a circle
    double a = shapes.back().area(); // expect ~12.566...
}

For each scenario, state exactly what goes wrong, why, and provide a corrected version.

Constraints & Assumptions

  • C++17, single-threaded.
  • Buffer is intended to have value semantics: copyable, with each copy independently owning its own buffer.
  • The polymorphic shapes are meant to be stored and later queried without losing their dynamic type.
  • Prefer standard idioms (RAII, Rule of Five, smart pointers) over manual reference counting.

Clarifying Questions to Ask

  • Should Buffer be deep-copyable, move-only, or non-copyable? (That decides which special members to write or =delete .)
  • Is exception safety (a strong guarantee on assignment) in scope, or only ownership correctness?
  • For the shapes, do we own the objects (so we must clone and delete them) or merely reference objects owned elsewhere?
  • May I use std::unique_ptr / std::shared_ptr , or should the fix be raw-pointer-only to demonstrate the Rule of Five explicitly?

What a Strong Answer Covers Premium

Follow-up Questions

  • How does copy-and-swap deliver the strong exception guarantee, and what does it require of swap and the move constructor?
  • When would you make Buffer move-only ( =delete the copies) instead of deep-copyable, and how would call sites change?
  • Why is deleting a derived object through a base pointer with a non-virtual destructor undefined behavior?
  • How would a std::variant<Circle, Square, ...> or another closed sum type compare to the clone() -based open polymorphism for storing heterogeneous shapes?
Loading comments...

Browse More Questions

More Software Engineering Fundamentals•More Sig•More Software Engineer•Sig Software Engineer•Sig Software Engineering Fundamentals•Software Engineer Software Engineering Fundamentals

Write your answer

Your first approved answer each day earns 20 XP.

Sign in to write your answer.
PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.