Katkat

Implement a Unique Pointer and Vector

Chicago Trading CompanySoftware Engineer · Technical Screen

Last updated

This problem tests your understanding of C++ RAII, move semantics, template metaprogramming, and manual memory management by requiring the implementation of a scoped unique-ownership pointer and a custom dynamic array container.

Part 1: Unique Pointer

Implement a template class UniquePtr that manages the lifetime of a single object. It must be move-only (no copy constructor or copy assignment). It should support:

  • A constructor taking a raw pointer.
  • A destructor that releases memory.
  • The -> and * operators.
  • A release() method that gives up ownership and returns the raw pointer.

Part 2: Dynamic Vector

Implement a simplified Vector class that manages a contiguous array of type T. It must handle dynamic resizing.

  • Implement push_back(T value), size(), and operator[].
  • When the internal capacity is reached, allocate a new buffer twice the size of the old one, move elements over, and deallocate the old buffer.
  • Ensure your implementation follows the Rule of Five to properly handle resources.

Constraints & Requirements

  • You must use new and delete to manage raw memory.
  • The Vector must work for types that are move-only (e.g., your UniquePtr).
  • Provide a brief explanation of how your Vector ensures exception safety during the resizing process.

Example

UniquePtr ptr(new int(10));
Vector> vec;
vec.push_back(std::move(ptr));
// vec[0] now contains the value 10

Hints

Hint 1

For the UniquePtr, use '= delete' on the copy constructor and assignment operator to enforce move-only semantics.

Hint 2

For the Vector, use 'std::move' when transferring elements from the old buffer to the new buffer to avoid unnecessary copies.

Hint 3

Consider implementing a 'swap' method in your Vector class to simplify the assignment operator and maintain the strong exception guarantee.

Follow-up questions

  • How would you modify your UniquePtr to support custom deleters (e.g., for file handles or custom allocators)?
  • If your Vector stores objects that throw exceptions during copy/move operations, how would you ensure the class remains in a valid state?
  • Explain the performance implications of 'std::vector::push_back' and how the amortized time complexity of O(1) is achieved.