Dynamic Stack  «Prev  Next»
Lesson 1

Constructing a Dynamically Sized Stack in Modern C++

This module explains how to construct a dynamically sized stack by designing a C++ class that owns memory safely. You’ll start with a simple stack of characters and evolve it into a robust, modern implementation.

By the end of the module, you will understand:

  1. How constructor overloading enables different initializations (default capacity, custom capacity, initial contents).
  2. Why copy constructors matter when a class owns resources (deep copy vs. shallow copy).
  3. How destructors (and modern RAII) ensure memory and other resources are released correctly.

The core theme is ownership: when your class allocates memory dynamically, it must also define how that memory is copied, moved, and cleaned up. That’s exactly what constructors, copy constructors, and destructors are about.

Two meanings of “stack” in C++

In C++, the word stack is used in two different ways:

This module is about the stack ADT. However, understanding the call stack and the heap is essential because a dynamically sized stack class typically stores its elements in dynamically allocated memory.


Stack vs. heap: where objects and buffers live

An automatic variable is created when its definition is executed and is typically stored in the program’s call stack. The call stack has a fixed size (configurable on many platforms), and memory for automatic variables is released automatically when the scope ends.

The heap (also called the free store) is a larger pool of memory used for objects whose lifetime must extend beyond a single scope. You can request heap memory at runtime. Historically, this was done with new and released with delete.

A “dynamically sized” stack ADT typically means: the stack’s internal storage capacity can be chosen at runtime (or can grow as needed). Either approach involves heap-based storage, so memory ownership must be designed carefully.

Freeing memory: what delete does (and why RAII is better)

If you allocate memory manually, you must also release it manually. Forgetting to release memory causes a leak; releasing it twice causes undefined behavior. One common safety pattern is to reset a pointer after releasing what it points to:

delete pvalue;     // release memory pointed to by pvalue
pvalue = nullptr;  // reset the pointer

Resetting the pointer helps prevent accidental use of a dangling address. However, modern C++ best practice is to avoid “naked” owning pointers entirely. Instead, prefer RAII-managed types such as:

  • std::vector<T> for dynamic arrays
  • std::string for text buffers
  • std::unique_ptr<T[]> when you truly need an owning dynamic array with pointer semantics

In this module, you’ll see the classic new[]/delete[] approach because it makes copy constructors and destructors “visible”. But you’ll also see the modern RAII approach, because that’s what you should use in current C++ code.

What is the Stack ADT?

Stack ADT

A stack is a LIFO data structure. Unlike a list, you do not insert or remove elements at arbitrary positions. You interact with the top of the stack:

  • push: add an element to the top
  • pop: remove the most recently pushed element
  • peek/top: inspect the top element without removing it

Stacks are widely used: function calls (call stack), expression evaluation, undo/redo features, parsing, and matching parentheses are all classic examples. In this module, we’ll focus on implementing the stack ADT as a C++ class with runtime-controlled storage.


How we’ll construct a dynamically sized stack in this module

The implementation path is intentionally incremental:

  1. Start with a class skeleton: define the stack’s invariants (capacity, current size, buffer ownership).
  2. Add constructors: default capacity and custom capacity (constructor overloading).
  3. Add a copy constructor: ensure deep-copy behavior when the class owns its storage.
  4. Add a destructor: release resources reliably (or replace raw ownership with RAII and use the Rule of Zero).

After that foundation is in place, you can safely build stack functionality (push/pop) and apply the structure to real tasks.


SEMrush Software