Back to C++
2026-01-068 min read

pointers to (C++)

Learn pointers to (C++) step by step with clear examples and exercises.

Title: Mastering Pointers in C++ - A full guide

Why This Matters

Pointers are a fundamental concept in C++ that play a crucial role in understanding dynamic memory allocation, function arguments, and complex data structures like arrays, linked lists, trees, and graphs. They provide direct access to memory, which is essential for solving real-world programming problems, debugging, and understanding low-level system operations.

Prerequisites

Before diving into pointers, it's essential to have a solid foundation in the following topics:

  1. Basic C++ syntax
  2. Variables and data types
  3. Operators and expressions
  4. Control structures (if-else, loops)
  5. Functions and function overloading
  6. Arrays and multi-dimensional arrays
  7. Understanding memory management in C++
  8. Familiarity with the standard library, such as ``
  9. Understanding of basic data structures like arrays and linked lists
  10. Knowledge of operator precedence and associativity
  11. Comfortable working with functions and function prototypes

Core Concept

What is a Pointer?

A pointer is a variable that stores the memory address of another variable. It allows you to access and manipulate data stored in memory directly. In C++, pointers are declared using the asterisk (\*) symbol.

int num = 10; // Declaring an integer variable named 'num' with value 10
int* ptr; // Declaring a pointer 'ptr' that can store the address of an integer variable
ptr = # // Assigning the memory address of 'num' to the pointer 'ptr' using the '&' operator (address-of)

Pointer Types

  1. Basic Pointers: Point to variables of specific data types, like int*, char*, or double*.
  2. Pointer to a Pointer: Used when you need to store the address of another pointer, like int**.**
  3. Array Pointers: Represent an array as a contiguous block of memory and are often used for dynamic memory allocation, like int* arr; (equivalent to int arr[10];).
  4. Pointer to Function: Allows you to store function addresses and call functions dynamically, like void (*func)();.
  5. Smart Pointers: Advanced C++ constructs that automatically manage memory allocation and deallocation, such as std::unique_ptr, std::shared_ptr, and std::weak_ptr.

Pointer Arithmetic

Pointers can be incremented or decremented to move through memory locations. The size of the data type being pointed to determines how much each pointer step represents:

int arr[] = {1, 2, 3, 4, 5};
int* ptr = &arr[0]; // Initialize pointer 'ptr' to the first element in the array
ptr++; // Move the pointer to the next memory location (equivalent to &arr[1])

Pointer Dereference

To access the data stored at a given memory address, you can dereference the pointer using the asterisk (\*) symbol:

int num = 10;
int* ptr = #
cout << *ptr; // Outputs '10' (dereferencing the pointer to access the value stored at its memory address)

Pointer Null and Address-of Operator

The null pointer (nullptr) is used to represent a non-initialized or invalid pointer:

int* ptr = nullptr; // Initializing a pointer 'ptr' with a null value

To obtain the memory address of a variable, use the address-of operator (&):

int num = 10;
int* ptr = &num; // Assigning the memory address of 'num' to the pointer 'ptr' using the '&' operator (address-of)

Pointer Operations

Pointer Addition and Subtraction

You can add or subtract integers to or from a pointer to move it a specific number of steps:

int arr[] = {1, 2, 3, 4, 5};
int* ptr = &arr[0]; // Initialize pointer 'ptr' to the first element in the array
ptr += 2; // Move the pointer two elements forward (equivalent to &arr[2])

Pointer Comparison

You can compare pointers to check if they point to the same memory location or if one comes after another:

int arr[] = {1, 2, 3, 4, 5};
int* ptr1 = &arr[0]; // Initialize pointer 'ptr1' to the first element in the array
int* ptr2 = &arr[2]; // Initialize pointer 'ptr2' to the third element in the array
if (ptr1 < ptr2) { // Check if 'ptr1' comes before 'ptr2' in memory
cout << "ptr1 is before ptr2" << endl;
} else {
cout << "ptr1 is after ptr2" << endl;
}

Worked Example

Let's create a simple program that demonstrates pointers in action:

#include <iostream>
using namespace std;

int main() {
int num = 10;
int* ptr = &num;

cout << "The value of 'num' is: " << num << endl; // Outputs 'The value of 'num' is: 10'
cout << "*ptr is: " << *ptr << endl; // Outputs '*ptr is: 10' (dereferencing the pointer to access its value)
cout << "Address of 'num': " << &num << endl; // Outputs 'Address of 'num': 0x7ffee4bff5e8' (the memory address of 'num')

*ptr = 20; // Changing the value stored at the memory address pointed by 'ptr'
cout << "The value of 'num' after changing it through the pointer is: " << num << endl; // Outputs 'The value of 'num' after changing it through the pointer is: 20'

int arr[] = {1, 2, 3, 4, 5};
int* ptrArr = &arr[0]; // Initialize pointer 'ptrArr' to the first element in the array
cout << "The value of the first element in the array is: " << *ptrArr << endl; // Outputs 'The value of the first element in the array is: 1'
cout << "The address of the second element in the array is: " << &arr[1] << endl; // Outputs 'The address of the second element in the array is: 0x7ffee4bff5ec'
ptrArr++; // Move the pointer to the next memory location (equivalent to &arr[1])
cout << "*ptrArr is: " << *ptrArr << endl; // Outputs '*ptrArr is: 2' (dereferencing the pointer to access its value)

return 0;
}

Common Mistakes

  1. Forgetting to initialize a pointer: Before using a pointer, make sure it has been initialized with a valid memory address or set to nullptr.
  2. Accessing invalid memory addresses: Be careful not to dereference a null pointer or move the pointer out of bounds of an array.
  3. Incorrectly declaring pointers: Ensure that you declare pointers with the appropriate data type, such as int*, char*, or double*.
  4. Forgetting to dereference a pointer: When using a pointer in an assignment or comparison operation, make sure to include the asterisk (\*) symbol to access the value stored at its memory address.
  5. Confusing pointers and references: References are implicitly initialized aliases for other variables. Be mindful of when to use each one.
  6. Memory leaks: When using dynamic memory allocation, don't forget to deallocate memory once it is no longer needed to avoid memory leaks.
  7. Incorrect pointer arithmetic: Ensure that pointer arithmetic operations do not move the pointer out of bounds of an array or cause undefined behavior.
  8. Misusing smart pointers: Understand the differences between std::unique_ptr, std::shared_ptr, and std::weak_ptr and use them appropriately.
  9. Not understanding the difference between stack and heap memory: Pointers can allocate memory on both the stack (local variables) and the heap (dynamic allocation). Be aware of the differences in how these two types of memory are managed.
  10. Not properly handling exceptions with new and delete: When using dynamic memory allocation, ensure you handle exceptions properly to avoid resource leaks when an exception is thrown during memory allocation or deallocation.

Practice Questions

  1. Write a program that declares an array of 10 integers, initializes it with values from 1 to 10, and prints the sum of all elements using a pointer.
  2. Given the following code snippet:
int num = 10;
int* ptr = &num;
int* arr[5] = {ptr, &num, nullptr, ptr + 3, (int*)&ptr};

What is the value stored in each element of the arr array?

  1. Write a program that dynamically allocates an array of 10 integers on the heap using new, initializes it with values from 1 to 10, and prints the sum of all elements using a pointer. Don't forget to deallocate the memory once you are done!
  2. Write a program that creates a simple linked list using pointers, where each node contains an integer value and a pointer to the next node. Implement functions to insert a new node at the beginning and end of the list, as well as a function to print the values in the list.

FAQ

  1. Why are pointers important in C++? Pointers provide a way to manipulate memory directly, which is essential for working with complex data structures and understanding low-level system operations. They also play a crucial role in solving real-world programming problems and debugging.
  2. How do I initialize a pointer to an array? To initialize a pointer to an array, use the address-of operator (&) on the first element of the array:
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = &arr[0]; // Initialize 'ptr' with the memory address of the first element in the array
  1. What is the difference between a pointer and a reference? Pointers are variables that store memory addresses, while references are implicitly initialized aliases for other variables. References have fixed memory locations and cannot be null or reassigned, whereas pointers can be null or changed to point to different memory addresses.
  2. How do I check if a pointer is null? To check if a pointer is null, compare it with nullptr:
int* ptr = nullptr; // Initialize 'ptr' with a null value
if (ptr == nullptr) {
cout << "The pointer is null" << endl;
} else {
cout << "The pointer is not null" << endl;
}
  1. How can I dynamically allocate memory using pointers? To dynamically allocate memory, use the new operator:
int* ptr = new int[10]; // Allocate an array of 10 integers on the heap and initialize 'ptr' with its address
// ... Use the pointer as needed ...
delete[] ptr; // Deallocate the memory once it is no longer needed to avoid a memory leak
  1. What happens if I don't deallocate dynamically allocated memory? If you don't deallocate dynamically allocated memory, a memory leak occurs, which can cause your program to run out of memory and potentially crash.
  2. How do I find memory leaks in my C++ program? To find memory leaks in your C++ program, use tools like Valgrind or Visual Studio's Memory Usage Analyzer. These tools help identify areas where memory is allocated but not properly deallocated.
  3. What are smart pointers and why should I use them? Smart pointers are advanced C++ constructs that automatically manage memory allocation and deallocation, providing a safer alternative to traditional raw pointers. They help avoid common errors like memory leaks and double-free errors, making your code more robust and easier to maintain.
  4. How do I handle exceptions with new and delete? To handle exceptions when using new and delete, wrap the allocation and deallocation in a try-catch block:
try {
int* ptr = new int[10]; // Allocate an array of 10 integers on the heap
// ... Use the pointer as needed ...
} catch (std::bad_alloc& e) {
cout << "An error occurred during memory allocation: " << e.what() << endl;
}
delete[] ptr; // Deallocate the memory once it is no longer needed to avoid a memory leak

1

pointers to (C++) | C++ | XQA Learn