What “Dynamic Memory” Really Means

Memory in a program is of two main types:

Static / Automatic memory → decided at compile time
Dynamic memory → decided at runtime

Dynamic memory means:
memory is requested while the program is running, not before.

Problem with Normal Variables (Why Dynamic Memory is Needed)

When you write:

 
int x;

This memory:
• is fixed
• size cannot change
• destroyed automatically when scope ends

Example:

 
void func() {
int x = 10;
}

When func() ends:
• memory of x is destroyed
• you cannot access it anymore

But sometimes:
• size is unknown
• data must survive longer
• memory must be controlled manually

This is where dynamic memory is needed.

Where Dynamic Memory Lives (VERY IMPORTANT)

Dynamic memory is allocated in a special memory area called the:

Heap

Memory areas:

AreaPurpose
StackLocal variables, automatic
HeapDynamic memory (manual)

• Stack → fast, automatic
• Heap → flexible, manual

new Operator 

What new Does Internally

When you write:

 
int *p = new int;

The system does four things:

  1. Finds free memory in heap

  2. Allocates enough bytes for int

  3. Returns the address of that memory

  4. Stores the address in pointer p

Memory view (example):

 
Heap:
0x5000 → uninitialized int

Stack:
p → 0x5000

Assigning Value to Dynamic Memory

 
int *p = new int;
*p = 10;

Or directly:

 
int *p = new int(10);

Now heap memory contains:

 
0x5000 → 10

Why Pointer is REQUIRED

Dynamic memory:
• has no variable name
• only accessible via pointer

This is illegal:

 
new int; // memory lost immediately

Correct:

 
int *p = new int;

Example 1: Basic Dynamic Variable

 
#include <iostream>

using namespace std;
int main() {
int *p = new int(25);
cout << "Value: " << *p << endl;
cout << "Address: " << p << endl;
delete p;
p = nullptr;
return 0;
}

Explanation:
• memory allocated at runtime
• accessed using pointer
• manually deleted

Dynamic Memory for Arrays (VERY IMPORTANT)

Static Array Problem

 
int arr[10];

Size:
• fixed
• must be known at compile time

Dynamic Array Solution

 
int *arr = new int[5];

Now:
• memory allocated in heap
• size decided at runtime

Memory layout:

 
Heap:

0x6000 → arr[0]
0x6004 → arr[1]
0x6008 → arr[2]
0x600C → arr[3]
0x6010 → arr[4]

Example 2: Dynamic Array Input

 
#include <iostream>

using namespace std;
int main() {
int n;
cout << "Enter size: ";
cin >> n;
int *arr = new int[n];
for(int i = 0; i < n; i++) {
cin >> arr[i];
}
for(int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
delete[] arr;
arr = nullptr;
return 0;
}

Important:
delete[] is REQUIRED for arrays

delete Operator 

What delete Really Does

 
delete p;

Steps:

  1. Frees heap memory

  2. Memory becomes available again

  3. Pointer still holds old address (DANGEROUS)

That pointer becomes:
Dangling pointer

Why nullptr is Important

After delete:

 
p = nullptr;

This ensures:
• pointer does not point to garbage
• safer memory handling

Difference Between delete and delete[]

AllocationDeallocation
new intdelete p
new int[n]delete[] p

Wrong usage causes:
• memory leaks
• undefined behavior

Memory Leak (VERY IMPORTANT)

What is Memory Leak?

Memory leak happens when:
• memory is allocated
• but never deleted

Example:

 
int *p = new int(10);
// no delete

Result:
• memory stays occupied
• program wastes RAM

In long-running programs:
• crash
• slow performance

Correct Pattern (Best Practice)

 
int *p = new int(10);

// use memory

delete p;
p = nullptr;

Example 3: Dynamic Memory in Function

 
int* createNumber() {
int *p = new int(50);
return p;
}
int main() {
int *x = createNumber();
cout << *x << endl;
delete x;
x = nullptr;
}

Why this works:
• memory is in heap
• survives function end
• controlled by programmer

Common Errors (VERY IMPORTANT)

1. Using memory after delete

 
delete p;
cout << *p; // ❌ dangerous

2. Double delete

 
delete p;
delete p; // ❌ crash

3. Forgetting delete

 
new int; // ❌ leak

Dynamic Memory vs Stack Memory 

FeatureStackHeap
AllocationAutomaticManual
SpeedFastSlower
SizeLimitedLarge
LifetimeScope-basedProgrammer-controlled