Pointers and Arrays: Understanding Their Relationship and Use Cases in C++
Have you ever seen a treasure map?
The map itself isn’t the treasure, right? It just shows you where the treasure is hidden. You follow the map to reach the real thing.
In C++, pointers are like that treasure map — they don't hold the treasure (the actual value) but tell you where the treasure is kept in your computer's memory.
And arrays? Think of them like a row of treasure chests — one after another — lined up neatly. Each chest (element) holds something valuable, and each has its own spot.
Today, we'll explore how pointers and arrays are connected, how they work individually, and how you can use them together smartly.
Pointers vs Arrays
Imagine you are at a big library.
- The bookshelves are fixed — standing there in one place, holding books in a row.
- But you — a visitor with a map — can move around freely, visiting different bookshelves, different sections, and even different libraries if you want!
In C++,
- Arrays are like bookshelves — fixed-sized, ordered collections, sitting in one memory area.
- Pointers are like visitors with a map — they can point anywhere, move around, change what they are pointing to.
Let’s break this down properly!
1. Memory and Flexibility
Array:
- An array is fixed in size once created.
- It stays in the same memory location.
- Example:
int arr[3] = {1, 2, 3};
This arr always holds exactly 3 integers, no more, no less.
Pointer:
- A pointer is flexible — it can point to any memory location you tell it to.
- You can even make it point to a new block of memory later!
- Example:
int* p;
p = new int[3]; // Now p points to an array of 3 integers
Summary:
Arrays are stuck in place. Pointers can roam!
2. Size Information
- Array:
The size of an array (how many elements it holds) is known by the compiler.
So you can easily get its size like this:
int arr[5];
int size = sizeof(arr) / sizeof(arr[0]); // Gives 5
- Pointer:
A pointer doesn't know how many elements it points to.
You have to remember the size yourself.
Summary:
Arrays know their size. Pointers don’t — you have to keep track!
3. Declaration and Syntax
Array:
- Simple and direct.
- Example:
int arr[4] = {1, 2, 3, 4};
Pointer:
- Needs to be declared with a *, and usually assigned an address or memory using & or new.
- Example:
int* p;
int x = 5;
p = &x; // p points to x
Summary:
Arrays are simple to declare. Pointers need a bit more setup!
4. Relationship Between Them
- The name of an array (arr) acts like a pointer to its first element (&arr[0]).
- You can actually use pointers to move through an array!
Example:
int arr[3] = {10, 20, 30};
int* p = arr; // Same as &arr[0]
cout << *p << endl; // 10
cout << *(p + 1) << endl; // 20
cout << *(p + 2) << endl; // 30
Summary:
Arrays and pointers are best friends — they can work together beautifully!
5. When to Use Which?
- Use Arrays when:
- You know the number of elements in advance.
- You want simplicity.
- Example: Storing marks of 5 students.
- Use Pointers when:
- You need to allocate memory during runtime (dynamic memory).
- You want more flexibility (resize, move).
- Example: Taking input from users where the number of inputs is unknown.
Simple Rule:
Known size?
Use arrays.
Unknown or flexible size?
Use pointers.
Array of Pointers
Imagine you have a group of friends, and each friend has their own home address.
Now, you make a list (maybe on your phone) where you store just the addresses of all your friends.
You are not storing the friends themselves in your phone — only where they live!
That’s exactly what an Array of Pointers is in C++.
It’s a list where each item holds an address — a memory location — instead of holding the actual data.
What Does an Array of Pointers Look Like?
In C++, you can create an array where each element is a pointer.
Example:
int a = 10, b = 20, c = 30;
int* arr[3]; // Array of 3 integer pointers
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
Explanation:
- arr is an array that can hold 3 pointers to integers.
- arr[0] holds the address of a.
- arr[1] holds the address of b.
- arr[2] holds the address of c.

So, when you use *arr[0], it will give you the value at the address — which is 10!
Think of it like:
Index | Address it holds | Actual Value |
---|---|---|
0 | Address of a | 10 |
1 | Address of b | 20 |
2 | Address of c | 30 |
How to Access Values?
Just like opening the door after knowing someone's home address!
Example:
cout << *arr[0] << endl; // Output: 10
cout << *arr[1] << endl; // Output: 20
cout << *arr[2] << endl; // Output: 30
Each time, you are following the address (pointer) and getting the actual data!
Pointer to an Array
Imagine you and your family are planning a road trip.
Instead of remembering the address of each hotel, park, and restaurant separately, you decide to just remember the address of the entire travel plan notebook!
You have one pointer to the whole list, instead of pointers to each tiny thing.
In C++, this idea is called Pointer to an Array.
What is a Pointer to an Array?
A Pointer to an Array is a pointer that stores the address of an entire array — not just a single element!
- It points to the whole group of elements together.
- It treats the array as one single unit.
How to Declare a Pointer to an Array?
Here’s the basic formula:
type (*pointer_name)[size_of_array];
Looks a little scary at first, right?
Don't worry, it’s actually very simple once you understand it!
Let’s break it down with an example:

int arr[5] = {10, 20, 30, 40, 50};
// Creating a pointer to an array of 5 integers
int (*p)[5];
p = &arr; // p now points to the entire array
What's happening here?
- arr is an array of 5 integers.
- p is a pointer to an array of 5 integers.
- p = &arr means p now holds the address of the whole array.
How to Access Elements Using Pointer to an Array?
Once you have the pointer, you can access elements like this:
cout << (*p)[0] << endl; // Output: 10
cout << (*p)[1] << endl; // Output: 20
cout << (*p)[2] << endl; // Output: 30
Why the (*p)?
- p points to the whole array, so first, we do *p to get the actual array.
- Then [0], [1], [2] to access the elements normally.
Think of it like:
First open the travel notebook (*p), then go to the specific page ([i]).
Difference Between Pointer to Array and Array of Pointers
Concept | Meaning |
---|---|
Array of Pointers | Each element is a pointer to some value |
Pointer to an Array | One pointer pointing to the whole array |
Tiny Example:
Array of Pointers:
int* arr[3]; // An array with 3 pointers inside
Pointer to an Array:
int (*p)[3]; // A pointer that points to an array of 3 integers
When Would You Use a Pointer to an Array?
Good question!
- When you want to pass an entire array to a function as a single pointer.
- When you want to work with a full block of data together.
- When you need better control over large data groups.
Example:
Suppose you want to write a function that works with an entire array:
void printArray(int (*p)[5]) {
for(int i = 0; i < 5; i++) {
cout << (*p)[i] << " ";
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printArray(&arr); // Passing address of the entire array
}
Output:
1 2 3 4 5
Here:
- p is a pointer to the array.
- *p gives access to the actual array inside the function.
Final Simple Tip :
Array of Pointers = many small maps to many small places.
Pointer to an Array = one big map to a big place!
Pointer to a Pointer
Imagine this:
You are on a treasure hunt. But the clue you find doesn’t take you directly to the treasure.
Instead, the clue tells you where to find another map, and that second map finally leads you to the treasure!
In C++, this idea is called a Pointer to a Pointer.
- One pointer points to another pointer,
- And that pointer finally points to the actual data.
What is a Pointer to a Pointer?
Normally, a pointer stores the address of a variable.
But sometimes, we need a pointer that stores the address of another pointer.
That’s when we use a Pointer to a Pointer.
In simple words:
Pointer to a Pointer = A clue to find another clue that finally finds the treasure!
How to Declare a Pointer to a Pointer?
It’s super simple!
You just add two stars (**) while declaring:
type** pointer_name;
Example:
int a = 5;
int* p = &a; // p points to a
int** q = &p; // q points to p
Imagine:
Name | What it holds | Points to |
---|---|---|
a | 5 | (value itself) |
p | Address of a | (points to a) |
q | Address of p | (points to p) |

How to Access the Value?
If you want to finally get the value (5), you have to unwrap it step-by-step:
cout << a << endl; // 5
cout << *p << endl; // 5 (p points to a)
cout << **q << endl; // 5 (q points to p which points to a)
Think of it like:
- First open the first map (q → p)
- Then open the second map (p → a)
- Then find the treasure (value of a)!
Why Do We Need a Pointer to a Pointer?
Good question! Let’s see a few reasons:
1. Changing a Pointer inside a Function
Normally, if you pass a pointer to a function, you can change the data it points to, but you can't change the pointer itself.
If you want to change the actual pointer (where it points), you need a pointer to a pointer.
Example:
void updatePointer(int** pp) {
static int b = 20;
*pp = &b; // Now, p will point to b
}
int main() {
int a = 10;
int* p = &a;
updatePointer(&p); // Passing address of p
cout << *p << endl; // Output: 20
}
Here:
- p originally pointed to a.
- After calling updatePointer, it points to b!
Without using int**, this wouldn't be possible.
2. Working with Dynamic 2D Arrays
When you create a 2D array dynamically, you use pointers to pointers.
Example:
int** arr = new int*[3]; // Array of 3 integer pointers
for (int i = 0; i < 3; i++) {
arr[i] = new int[4]; // Each pointer points to an array of 4 integers
}
// Don't forget to free memory later!
for (int i = 0; i < 3; i++) {
delete[] arr[i];
}
delete[] arr;
Here,
- arr is a pointer to a pointer — it points to multiple rows.
Simple Way to Remember
Pointer to Pointer = Map → Another Map → Treasure!
- First map (q) shows where second map (p) is.
- Second map (p) shows where the treasure (variable) is.
Array Traversal using a pointer
Imagine you are in a library.
You are standing at the very first shelf.
You move one step right to go to the next shelf, one more step to the next, and so on — without needing to remember all the shelf numbers.
You just keep moving step-by-step!
In C++, using a pointer to move through an array is exactly like this.
- You start at the first element (first shelf).
- Then move the pointer ahead to go to the next element.
- Keep moving until you reach the end!
This way of moving through an array using a pointer is called Array Traversal using a Pointer.
How does it work?
Normally, we access array elements using indexes like this:
int arr[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
But with pointers, we can move through the array without using indexes!
Traversing an Array Using a Pointer
Example:
int arr[5] = {10, 20, 30, 40, 50};
int* p = arr; // Pointing to the first element of array
for (int i = 0; i < 5; i++) {
cout << *(p + i) << " ";
}
Output:
10 20 30 40 50

Step-by-Step Explanation
- int* p = arr;
- Means p points to the first element (arr[0]).
- *(p + i), Like:
- Means go i steps forward from p, and get the value.
- *(p + 0) = arr[0] = 10
- *(p + 1) = arr[1] = 20
- *(p + 2) = arr[2] = 30
- and so on.
It's just like taking steps in the library aisle!
Another Way: Moving the Pointer Itself
You can also move the pointer itself without using i:
int arr[5] = {10, 20, 30, 40, 50};
int* p = arr; // Pointer to first element
for (int i = 0; i < 5; i++) {
cout << *p << " "; // Print current value
p++; // Move to next element
}
Here:
- First, p points to arr[0], prints 10.
- Then, p++ moves to arr[1], prints 20.
- And so on until the end!
Imagine:
Pointer (p) Position | Points to | Value |
---|---|---|
p | arr[0] | 10 |
p + 1 | arr[1] | 20 |
p + 2 | arr[2] | 30 |
p + 3 | arr[3] | 40 |
p + 4 | arr[4] | 50 |
Every time you increment the pointer, you step one shelf forward!
Things to Remember
- In C++, when you add 1 to a pointer, it doesn’t move by 1 byte — it moves by the size of the data type.
- For int, usually moves 4 bytes forward.
- For char, moves 1 byte forward.
- Make sure you don't go beyond the array boundary — otherwise, it’s like walking outside the library!
Real-World Use: Why Traverse Using a Pointer?
- Efficiency: Sometimes pointer traversal is faster and uses fewer resources.
- Low-level operations: When working close to memory (like in embedded systems), pointer traversal is very useful.
- Flexibility: You can easily pass pointers to functions and move around big chunks of data.