Skip to main content
Data Structures
CHAPTER 04 Beginner

Dynamic Arrays

Updated: May 17, 2026
15 min read

# CHAPTER 4

Dynamic Arrays

1. Introduction

In the previous chapter, we learned a terrifying limitation of standard Arrays: they have a fixed size. If you allocate an array of 5 elements, and later need to add a 6th, the program will crash with an Out of Bounds error. In the real world, you rarely know exactly how much data you will have (e.g., how many items a user will add to a shopping cart). To solve this, software engineers invented the Dynamic Array. This is the underlying architecture behind Java's ArrayList, C++'s std::vector, and Python's standard list. In this chapter, we will pull back the curtain and see exactly how languages magically "grow" arrays in the background.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the difference between *Capacity* and *Size*.
  • Understand the algorithmic process of Array Resizing.
  • Understand Amortized Time Complexity.
  • Write custom logic to simulate a Dynamic Array in static languages.

3. The Core Concept: Size vs. Capacity

A dynamic array relies on a clever trick. It actually *is* a static array under the hood, but it allocates more memory than you ask for.
  • Size (or Length): The number of elements actually pushed into the array by the user.
  • Capacity: The physical number of memory slots currently reserved by the operating system.

Visualizing the Trick:

text
123
Array: [10] [20] [30] [Empty] [Empty]
Size: 3 (We only placed 3 items)
Capacity: 5 (The physical memory can hold up to 5)

When you push a 4th item, it goes into the empty slot. It is instantaneous O(1). But what happens when the Capacity fills up?

4. The Resizing Algorithm

When Size == Capacity, the dynamic array triggers a background algorithmic event called Resizing.

The 4 Steps of Resizing:

  1. 1. Allocate: The engine creates a brand new, empty static array in memory that is *double* the capacity of the old one (e.g., from 5 to 10).
  1. 2. Copy: The engine runs an O(n) loop to copy every single element from the old array into the new array.
  1. 3. Swap: The internal pointer of the array object is switched to point to the new, larger array.
  1. 4. Destroy: The old, small array is deleted from memory (Garbage Collection).

5. Implementing a Dynamic Array (Mental Model)

Let's look at how this logic is actually written in C++ (simplified).
cpp
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
// C++ Example: The mechanics of std::vector
#include <iostream>
using namespace std;

class MyDynamicArray {
private:
    int* arr;
    int capacity;
    int size;

public:
    MyDynamicArray() {
        capacity = 2; // Start small
        size = 0;
        arr = new int[capacity]; // Allocate physical static array
    }

    void push(int element) {
        if (size == capacity) {
            // TRIGGER RESIZE: Double the capacity!
            int newCapacity = capacity * 2;
            int* newArr = new int[newCapacity];
            
            // O(n) COPY OPERATION
            for (int i = 0; i < size; i++) {
                newArr[i] = arr[i];
            }
            
            delete[] arr; // Destroy old array
            arr = newArr; // Swap pointers
            capacity = newCapacity;
            cout << "Array resized to capacity: " << capacity << endl;
        }
        
        // O(1) Insertion
        arr[size] = element;
        size++;
    }
};

int main() {
    MyDynamicArray list;
    list.push(10); // Size 1, Cap 2
    list.push(20); // Size 2, Cap 2
    list.push(30); // Size 3, Cap 4 (Triggers resize!)
    return 0;
}

6. Amortized Time Complexity

You might be thinking: *"Wait! If pushing an element sometimes triggers an O(n) copy operation, isn't appending to a Dynamic Array mathematically slow?"* The answer lies in Amortized Analysis. Because we *double* the capacity every time we resize, the resizing event happens less and less frequently as the array gets larger. If we push 1,000 items, 990 of those pushes are instantaneous O(1). Only 10 of those pushes triggered a resize. If we average out the heavy O(n) operations across all the fast O(1) operations, the mathematical average is still O(1) Amortized Time.

7. Language Implementations

How do popular languages handle this natively?
  • Java (ArrayList): Grows by 50% (Capacity * 1.5).
  • C++ (std::vector): Grows by 100% (Capacity * 2).
  • Python (list): Uses a complex formula, roughly growing by 112%. Python lists are actually dynamic arrays of pointers, not raw data!

8. Memory Waste (The Tradeoff)

If you have an array with a capacity of 100,000, and it is full, and you push *one* more item, the capacity doubles to 200,000. You now have 99,999 empty memory slots sitting useless in RAM. This is the Space/Time Tradeoff. Dynamic arrays waste physical RAM space to guarantee mathematical algorithmic speed.

9. Common Mistakes

  • Pre-allocating poorly: In Java or C++, if you know you are going to push 10,000 items into a list, doing new ArrayList<>() will cause the array to resize and copy itself dozens of times during execution, slowing down your program. Always set an initial capacity: new ArrayList<>(10000).

10. Best Practices

  • Shrinking: Just as arrays grow, they should shrink. If you delete 90% of the elements in a dynamic array, most standard libraries will trigger a "Shrink" event, cutting the capacity in half to return the wasted RAM back to the operating system.

11. Exercises

  1. 1. If a dynamic array currently has a size of 4 and a capacity of 4, and it is programmed to double its capacity on resize, what will be the capacity after inserting 3 more elements?
  1. 2. Explain the difference between size() and capacity() in a C++ std::vector.

12. MCQs with Answers

Question 1

In the context of a Dynamic Array, what does the term "Capacity" refer to?

Question 2

When a Dynamic Array is completely full and a new element is appended, what is the FIRST step the internal algorithm must take?

Question 3

After allocating the new, larger array during a resize event, what computationally expensive operation must occur?

Question 4

Because resizing involves an O(n) copy operation, why do Computer Scientists still classify appending to a Dynamic Array as O(1) Time Complexity?

Question 5

What is the fundamental architectural tradeoff made by a Dynamic Array?

Question 6

Which of the following data structures in standard programming libraries is a Dynamic Array under the hood?

Question 7

If a Java ArrayList starts with a capacity of 10, and you plan to loop and insert 1 million elements, what performance issue will occur?

Question 8

How do you prevent the performance degradation described in the previous question?

Question 9

If a dynamic array has a capacity of 8 and a size of 8, and the engine doubles capacity on resize, what are the new size and capacity exactly AFTER the 9th element is successfully pushed?

Question 10

Why do dynamic arrays usually increase capacity by a multiplication factor (e.g., x2 or x1.5) rather than a fixed addition (e.g., +100 slots)?

13. Interview Preparation

Top Interview Questions:
  • *System Design:* "Explain the internal architectural mechanics of a Java ArrayList or Python list. Describe the exact lifecycle of memory allocation, resizing, copying, and garbage collection when the structure reaches maximum capacity."
  • *Conceptual:* "Define 'Amortized Time Complexity' and explain mathematically why inserting an element at the end of a Dynamic Array is considered O(1) despite the existence of the O(n) resize operation."

Common Pitfalls:

  • In an interview, if you are asked to design a real-time system (like trading software or medical device software) where "stutters" or "pauses" are completely unacceptable, do NOT use a Dynamic Array. The rare O(n) resize operation will cause a microsecond CPU freeze.

14. FAQs

Q: Do I ever need to write my own Dynamic Array class at work? A: Never. You will use std::vector or ArrayList 100% of the time. However, interviewing engineers will ask you to build one from scratch on a whiteboard to prove you understand pointers, memory leaks, and Big O mathematics.

15. Summary

Dynamic Arrays are a brilliant architectural abstraction. By quietly allocating more physical memory than requested, and implementing a multiplicative resizing algorithm, they combine the ultimate speed of static array math with the infinite flexibility required by modern web applications.

16. Next Chapter Recommendation

Arrays don't just hold numbers. When you link an array of characters together, you create the most important data structure for human communication: text. In Chapter 5: Strings and Character Arrays, we will dissect how memory structures process sentences, words, and alphabets.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·