C++: Dynamic Memory Allocation

Last updated: 2026-08-26

In previous lessons, variables and arrays were allocated on the stack — fixed in size, automatically freed when the function ends.

But if you need to store an uncertain amount of data (e.g., the user inputs 1000 integers, but you don't know at compile time), you need dynamic memory allocation — allocating memory on the heap.



1. Stack vs Heap

(1) 1.1 Two Memory Regions

Comparison Stack Heap
Allocation timing Determined at compile time Determined at runtime
Size Fixed (determined at compile time) Variable (requested at runtime)
Deallocation timing Automatic (when function ends) Manual (using delete)
Efficiency High Low
Use cases Local variables, arrays Dynamically-sized data

(2) 1.2 Everyday Analogy

Real-life Analogy Program Equivalent
Fast food restaurant (fixed menu, food served immediately after ordering) Stack
Buffet (take as much as you want) Heap


2. new and delete

(1) 2.1 Allocating Memory with new

Syntax:

▶ Example 2: Dynamic Memory Management (Difficulty ⭐)

TEXT 📖 Display only
Type* pointerName = new Type;

Output:

TEXT 📖 Display only
(Program output)

Example:

CPP
#include <iostream>

int main() {
 // Allocate an int on the heap
 int* p = new int; // p Pointing to int on the heap
 
 *p = 5; // Assign value to int on the heap
 std::cout << "*p = " << *p << std::endl; // 5
 
 return 0;
}

💡 Key point: new returns a pointer — pointing to the memory allocated on the heap.


(2) 2.2 Freeing Memory with delete

Syntax:

TEXT 📖 Display only
delete pointerName;

Example:

CPP
#include <iostream>

int main() {
 int* p = new int;
 *p = 5;
 
 std::cout << "*p = " << *p << std::endl;
 
 delete p; // ✅ Free heap memory
 p = nullptr; // ✅ Good practice:Set to nullptr after freeing
 
 return 0;
}

💡 Golden rule: new and delete must always come in pairs — every new needs a delete.


(3) 2.3 Forgetting delete Causes Memory Leaks

Error example:

CPP
#include <iostream>

void foo() {
 int* p = new int;
 *p = 5;
 // ❌ Forgot to write delete p;
} // Function ends, p is destroyed, but int on heap is not freed (memory leak)

int main() {
 for (int i = 0; i < 1000000; i++) {
 foo(); // Each call leaks 4 bytes
 }
 // Program memory usage keeps growing, may eventually crash
 return 0;
}

💡 Memory leak: Heap-allocated memory that is never freed and can no longer be accessed (because the pointer to it has been destroyed).



3. Dynamic Arrays

(1) 3.1 Allocating Arrays with new

Syntax:

TEXT 📖 Display only
Type* pointerName = new Type[size];

Example:

CPP
#include <iostream>

int main() {
 int n;
 std::cout << "Please enter the array size: ";
 std::cin >> n;
 
 // Allocate an array of n ints on the heap
 int* arr = new int[n];
 
 // Using the array
 for (int i = 0; i < n; i++) {
 arr[i] = i + 1;
 }
 
 // Output the array
 for (int i = 0; i < n; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
 
 // Freearray(Note:Use delete, not delete)
 delete arr;
 
 return 0;
}

💡 Key point: To free an array, use delete[] (with square brackets), not delete!


(2) 3.2 new and delete Must Be Paired Correctly

Allocation Deallocation
new int delete p;
new int[10] delete[] p;

Error example:

CPP
int* p = new int[10];
delete p; // ❌ Error: Should use delete[] p;


4. Dangling Pointers

(1) 4.1 What is a Dangling Pointer?

A dangling pointer is a pointer that points to already freed memory.

CPP
#include <iostream>

int main() {
 int* p = new int(5);
 delete p; // Free memory
 
 // ❌ Dangerous: p is now a dangling pointer
 std::cout << *p << std::endl; // Undefined behavior! May output garbage or crash
 
 return 0;
}

💡 Solution: Set the pointer to nullptr immediately after freeing:

CPP
delete p;
p = nullptr; // ✅ Good practice


5. Practice: Sorting a Dynamic Array

▶ Example 1: Selection Sort with a Dynamic Array (Difficulty ⭐⭐)

CPP
#include <iostream>

// Selection Sort
void selectionSort(int* arr, int n) {
 for (int i = 0; i < n - 1; i++) {
 int minIdx = i;
 for (int j = i + 1; j < n; j++) {
 if (arr[j] < arr[minIdx]) {
 minIdx = j;
 }
 }
 // Swap
 int temp = arr[i];
 arr[i] = arr[minIdx];
 arr[minIdx] = temp;
 }
}

int main() {
 int n;
 std::cout << "Please enter the array size: ";
 std::cin >> n;
 
 int* arr = new int[n]; // Dynamically allocate array
 
 std::cout << "Please enter " << n << " Integer: " << std::endl;
 for (int i = 0; i < n; i++) {
 std::cin >> arr[i];
 }
 
 selectionSort(arr, n); // Sort
 
 std::cout << "After sorting: " << std::endl;
 for (int i = 0; i < n; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
 
 delete[] arr; // Free memory
 arr = nullptr;
 
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
Please enter the array size: 
Please enter  Integer: 
After sorting: 
 

Running result:

TEXT 📖 Display only
Please enter the array size: 5
Please enter 5 Integer: 
5 3 1 4 2
After sorting: 
1 2 3 4 5


6. Common Errors

(1) 6.1 Double delete

Error example:

CPP
int* p = new int(5);
delete p;
delete p; // ❌ Error: Double free of same memory (undefined behavior)

Fix: Set to nullptr immediately after freeing (delete nullptr is safe).

TEXT 📖 Display only
delete p;
p = nullptr;

(2) 6.2 Forgetting delete

Error example:

CPP
int* arr = new int[10];
// ❌ Forgot to write delete[] arr;

Consequence: Memory leak.


❓ FAQ

Q Why use dynamic memory? Can't I just use arrays?
A If you know the size at compile time, arrays are fine. But if: > - The size is determined by user input > - The size might be very large (exceeding stack capacity) > - You need data to persist after a function ends

▶ Example 3: Dynamic Array (Difficulty ⭐)

CPP
#include <iostream>

int main() {
    int size = 5;
    int* arr = new int[size];

    for (int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }

    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    delete[] arr;

    return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
0 10 20 30 40
💡 Tip: new int[n] allocates an array, delete[] frees an array. Don't forget the []!



📖 Summary

📝 Exercises

  1. Basic (Difficulty ⭐): Use new to allocate a double, assign it 3.14, output it, then free it.

  2. Intermediate (Difficulty ⭐⭐): Let the user input n, use new to dynamically allocate an int array of size n, input n integers, find the maximum, then free the memory.

  3. Challenge (Difficulty ⭐⭐⭐): Implement a "dynamic array" class using dynamic memory (you'll learn classes later; use a struct for now):

  4. Include: int* data (pointer to heap array), int size (current size), int capacity (capacity)

  5. Implement a push_back function: if size == capacity, reallocate a larger block of memory (new a larger array, copy data over, free the old one)

  6. Test: add 100 elements


11. 🚀 Next Step

Now that you've learned dynamic memory allocation, let's move on to Pointers and References: Comprehensive Practice (Lesson 27) — reinforcing everything you've learned through integrated examples!

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏