C++ Pointers and Arrays

Relationship between Array and Pointers

In C++, pointer arithmetic involves manipulating the memory addresses held by pointers. Unlike other languages, C++ allows direct manipulation of pointers, providing unparalleled control over memory. Pointer arithmetic is primarily applied to pointers pointing to arrays, enabling efficient traversal and manipulation.

Pointer arithmetic involves adding or subtracting integers to/from pointers, resulting in a new memory address. The size of the data type to which the pointer points determines the actual memory offset.

  • The name of the array is a const pointer to the beginning of the array. It contains the address of first array element.

    int score[100];
    the score is equal to &score[0].
  • A pointer that points to the beginning of array can access any element of array using pointer arithmetic.

    int score[100];
    int *ptr = score;
    

    Now we can access fourth element of array as *(ptr + 3) or ptr[3]. Internally, any array element access using index is implemented using pointer.

  • A pointers variable can also store address of individual array elements like address of single variables.

    int score[100];
    int *ptr = &score[4];
    
  • On incrementing a pointer who is pointing to an array element, it will start pointing to next array element.

    int score[100];
    int *ptr = score;
    

    Currently, ptr is pointing to first element of array but when we increment it

    ptr = ptr + 1;
    

    It will start pointing to 1st element of array. Incrementing a pointer increases its value by the number of bytes of its data type.

    1. On incrementing, a pointer pointing to an integer(4 bytes) array jumps 4 bytes.
    2. On incrementing, a pointer pointing to a character(1 bytes) array jumps 1 bytes.

C++ Program to print array elements using array index and pointers

#include <iostream>
using namespace std;
 
int main () {
   int score[6] = {1, 2, 3, 4, 5, 6};
   int i, *ptr;
 
   // printing array elements using array index
   for(i = 0; i < 6; i++){
       cout << score[i] << " ";
   }
   cout << endl;
   
   // Initializing pointer
   ptr = score;
   // printing array elements using pointer
   for(i = 0; i < 6; i++){
       cout << *(ptr) << " ";
       // Incrementing pointer
       ptr++;
   }
   
   return 0;
}

Output
1 2 3 4 5 6
1 2 3 4 5 6

In above program, we first initialize a pointer with base address of an integer array. On incrementing this pointer inside for loop, it keeps on pointing to next array element.

  • Pointers and Arrays are interchangeable in many cases but their one difference. Name of an array is a constant pointer, which always points to first element of array. We can use array name in pointer arithmetics as long as we are not changing it's value.
    int score[100];
  • (score + 1) is a valid expression because here we are not changing value of score whereas *(score++) is invalid.

Pointer Arithmetic in Multidimensional Arrays

Pointer arithmetic is especially powerful when working with multidimensional arrays.

#include <iostream>

int main() {
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // Pointer to the beginning of the matrix
    int* ptr = &matrix[0][0]; 

    // Accessing elements using pointer arithmetic
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
            std::cout << "Element at (" << i << ", " << j << "): " 
               << *(ptr + i * 3 + j) << std::endl;
        }
    }
    return 0;
}  
  
Here, the nested loop uses pointer arithmetic to access elements of a 2D array.

Pointer Arithmetic and Strings

Pointer arithmetic is widely used in string manipulation, allowing for efficient traversal and modification of strings.

#include <iostream>

int main() {
    const char* greeting = "Hello, C++!";

    // Displaying characters using pointer arithmetic
    for (int i = 0; *(greeting + i) != '\0'; ++i) {
        std::cout << "Character " << i << ": " 
          << *(greeting + i) << std::endl;
    }

    return 0;
}
  
In this example, the loop traverses characters in a C-style string using pointer arithmetic.

Pointer Arithmetic and Memory Allocation

Dynamic memory allocation often involves pointer arithmetic, especially when managing arrays of data.

#include <iostream>

int main() {
    // Dynamic memory allocation for an array
    int* dynamicArray = new int[5];

    // Initializing array elements using pointer arithmetic
    for (int i = 0; i < 5; ++i) {
        *(dynamicArray + i) = i + 1;
    }

    // Displaying array elements
    for (int i = 0; i < 5; ++i) {
        std::cout << "Element " << i << ": " 
          << *(dynamicArray + i) << std::endl;
    }

    // Don't forget to free the allocated memory
    delete[] dynamicArray;

    return 0;
}
  
Here, *(dynamicArray + i) initializes and accesses elements in the dynamically allocated array.

Pointer Arithmetic in C++

In C++, arithmetic operations on pointer variable is similar to a numeric value. As we know that, a pointer in C++ is a variable used to store the memory address which is a numeric value. The arithmetic operations on pointer variable changes the memory address pointed by pointer. Not all arithmetic operations are valid for pointer variable, like multiplication and division. Here is the list of valid pointer arithmetic operations.

  • Incrementing a pointer.
  • Decrementing a pointer.
  • Adding a number to pointer.
  • Subtracting a number form a pointer.
  • Comparison on two pointers.
  • Subtracting two pointers.
And, here is the list of invalid pointer arithmetic operations.
  • Addition of two pointers.
  • Division of two pointers.
  • Multiplication of two pointers.

Adding a numbers to a Pointer

Addition of a number N to a pointer leads the pointer to a new memory location after skipping (N x size of pointer data type) bytes.

ptr + N =  ptr + (N * sizeof(pointer_data_type))

For example, Let ptr be an integer pointer, initially pointing to location 1000. The size of integer data type is 4 bytes. Then ptr + 5 = 1000 + 4*5 = 1020. Pointer ptr will now point at memory address 1020.


Subtracting Numbers from Pointers

Subtraction of a number N from a pointers is similar to adding a number except in subtraction the new location will be before current location by (N x size of pointer data type).

ptr - N =  ptr - (N * sizeof(pointer_data_ype))

For example, Let ptr be a double pointer, initially pointing to location 1000. The size of double data type is 6 bytes. Then ptr - 3 = 1000 - 6*3 = 982. Pointer ptr will now point at memory address 982.


Subtraction of Two Pointers

The difference between two pointer returns indicates “How apart the two Pointers are. It gives the total number of elements between two pointers. For example, Let size of integer is 4 bytes. If an integer pointer 'ptr1' points at memory location 10000 and integer pointer 'ptr' points at memory location 10008, the result of ptr2 - ptr1 is 2.


Incrementing a Pointer in C++

We use increment operator(++) to increment a pointer. The effect of incrementing an integer and an integer pointer is different. Let ptr be an integer pointer which points to the memory location 5000 and size of an integer variable is 4 bytes. Now, when we increment pointer ptr

ptr++;

it will point to memory location 5004 because it will jump to the next integer location which is 4 bytes next to the current location. Incrementing a pointer is not same as incrementing an integer value. On incrementing, a pointer will point to the memory location after skipping N bytes, where N is the size of the data type(in this case it is 4).

ptr++ is equivalent to ptr + (sizeof(pointer_data_type)).
"Incrementing a pointer increases its value by the number of bytes of its data type".

  • An integer(4 bytes) pointer on increment jumps 4 bytes.
  • A character(1 bytes) pointer on increment jumps 1 bytes.


Decrementing a Pointer in C++

We use decrement operator(--) to decrement a pointer. Decrementing a pointer will decrease its value by the number of bytes of its data type. Let ptr is originally pointing to memory location 5000. Hence, after

    ptr--;
ptr will point to 4996.
ptr--; is equivalent to ptr - (sizeof(pointer_data_type)).