Pointers and Arrays

In C++, pointers and arrays are very closely related. Here’s a little program to demonstrate this:

#include <iostream>

int main() {
    int numbers[] = {5, 2, 8, 1, 3};
    std::cout << "Memory address of first element: " << numbers << "\n";
    std::cout << "Also memory address of first element: " << &(numbers[0]) << "\n\n";

    std::cout << "Memory address of second element: " << numbers + 1 << "\n";
    std::cout << "Also memory address of second element: " << &(numbers[1]) << "\n\n";
    
    std::cout << numbers[0] << "   " << *numbers << "\n";
    std::cout << numbers[1] << "   " << *(numbers + 1) << "\n";

    return 0;
}

Sample Program Output (memory addresses may vary):

Memory address of first element: 0x61fe00
Also memory address of first element: 0x61fe00

Memory address of second element: 0x61fe04
Also memory address of second element: 0x61fe04

5   5
2   2

As you can see, the variable name for an array (e.g. “numbers” above) just represents a pointer to the array’s first element. In other words, its value is the same as the first element’s memory address.

In the above program, we also use what’s called pointer arithmetic (adding and subtracting numbers to/from pointers). Here, “numbers + 1” represents the memory address of the array’s element at index 1 (in other words, the second element). From the program’s output, you’ll see that the actual value of this address is 4 greater than “numbers“, not 1. This is because each element in the array takes up 4 bytes of memory, since each element is an int (as we saw in Variables and Basic Data Types).

Lastly, because of the above two characteristics, an array’s elements can be accessed by the dereferencing operation (“*“). Since “numbers” represents the memory address of the array’s first element, dereferencing that (with “*numbers“) provides the value of the first element (or, the element at index 0). Similarly, since “numbers + 1” represents the memory address of the array’s second element, dereferencing that (with “*(numbers + 1)” ) provides the value of the second element (or, the element at index 1).

Therefore, in the sample program, “numbers[x]” is practically equivalent to “*(numbers + x)“, where x is some index of the array.

Heap Arrays

When putting a variable on the heap, we get a pointer to that variable (e.g. in “int *number = new int(5);“, number is a pointer to the number 5). Similarly, when putting an array on the heap, we get a pointer to the array’s first element. This means that it behaves very similarly to an array on the stack (like in the first example program):

#include <iostream>

int main() {
    int *numbers = new int[5] {5, 2, 8, 1, 3};

    std::cout << "Memory address of first element: " << numbers << "\n";
    std::cout << "Also memory address of first element: " << &(numbers[0]) << "\n\n";

    std::cout << "Memory address of second element: " << numbers + 1 << "\n";
    std::cout << "Also memory address of second element: " << &(numbers[1]) << "\n\n";
    
    std::cout << numbers[0] << "   " << *numbers << "\n";
    std::cout << numbers[1] << "   " << *(numbers + 1) << "\n";

    delete[] numbers;

    return 0;
}

Sample Program Output (memory addresses may vary):

Memory address of first element: 0x25c24d0
Also memory address of first element: 0x25c24d0

Memory address of second element: 0x25c24d4
Also memory address of second element: 0x25c24d4

5   5
2   2

Just note that, to delete an array from the heap, we use “delete[]” (not “delete“).