Skip to content

Ch8: Pointers

TL;DR: Memory Addressing: A pointer stores a variable's memory address, occupies 8 bytes on 64-bit platforms, and is dereferenced using * to read or write the value at that address.

โšก Quick Reference

#include <iostream>

int main() {
    int value = 42;

    // type* ptr - Declare pointer storing the address of type.
    int* p_val = nullptr; // nullptr - Clean representation of an uninitialized address.

    // & - Address-of operator returning the memory location of a variable.
    p_val = &value;

    // * - Dereference operator accessing the actual value stored at pointer address.
    int copied_val = *p_val;

    // const type* - Pointer to const: address can change, value pointed to cannot.
    const int* p_const_val = &value;

    // type* const - Const pointer: address is fixed, value pointed to can change.
    int* const const_p_val = &value;

    // const type* const - Const pointer to const: address and value are both fixed.
    const int* const const_p_const_val = &value;

    // new - Allocates single variable on heap.
    int* p_heap = new int(100);
    // delete - Releases single heap-allocated memory space.
    delete p_heap;

    // new[] - Allocates dynamic array on heap.
    int* p_heap_array = new int[5];
    // delete[] - Releases dynamic array heap memory.
    delete[] p_heap_array;

    return 0;
}

๐Ÿง  Core Concepts

  • Memory Addressing: A pointer stores a variable's memory address, occupies 8 bytes on 64-bit platforms, and is dereferenced using * to read or write the value at that address.
  • Dynamic Allocation: Heap memory allocated via new persists until explicitly returned using delete (or delete[] for arrays) to avoid resource exhaustion.
  • Pointer Decay & Safety: Array names decay to pointers to their first element. Uninitialized or dangling pointers access garbage addresses and cause undefined behavior.

โš ๏ธ Pitfalls (Quick Scan)

Mistake Fix
Declaring multiple pointers on one line as int p, var; Always declare only one variable per line for pointers
Modifying a string literal using a non-const char Always use const char* for string literals or use char message[] = "Hello"; to create a mutable copy
Reassigning an array name to another address Use standard pointer variables if address reassignment is needed
Using std::size or range-based for loop on dynamic arrays Track array sizes manually and use standard indexed loops
Incrementing or decrementing array names directly Create a separate pointer variable to perform arithmetic operations
Subtracting or comparing pointers from different arrays Only subtract or compare pointers pointing within the same array
Dereferencing uninitialized or null pointers Always initialize pointers to nullptr and check them before dereferencing
Forgetting to free heap memory using delete or delete[] Always call delete or delete[] when heap allocations are no longer needed
Calling delete multiple times on the same pointer (double-free) Set pointers to nullptr immediately after deallocation
Using standard delete instead of delete[] for dynamic arrays Always use delete[] when freeing memory allocated with new[]

๐Ÿ“– Full Details

Cause โ†’ Effect โ†’ Fix with timestamp (click to expand) * **Declaring multiple pointers on one line as `int* p, var;`** -> **Only the first variable is a pointer; subsequent variables are standard types** -> **Always declare only one variable per line for pointers (10:00)** * **Modifying a string literal using a non-const `char*`** -> **Causes undefined behavior or runtime crash because literals reside in read-only memory (27:00)** -> **Always use `const char*` for string literals or use `char message[] = "Hello";` to create a mutable copy (27:00)** * **Reassigning an array name to another address** -> **Compile-time error because array names are non-modifiable lvalues** -> **Use standard pointer variables if address reassignment is needed (77:00)** * **Using `std::size` or range-based `for` loop on dynamic arrays** -> **Compile-time error or size evaluation failure because arrays decay to raw pointers** -> **Track array sizes manually and use standard indexed loops (81:00)** * **Incrementing or decrementing array names directly** -> **Compile-time error because array names are constant pointers** -> **Create a separate pointer variable to perform arithmetic operations (88:00)** * **Subtracting or comparing pointers from different arrays** -> **Undefined behavior or nonsensical address comparison results** -> **Only subtract or compare pointers pointing within the same array (117:00, 126:00)** * **Dereferencing uninitialized or null pointers** -> **Runtime program crashes or undefined behavior** -> **Always initialize pointers to `nullptr` and check them before dereferencing (140:00)** * **Forgetting to free heap memory using `delete` or `delete[]`** -> **Memory leak that accumulates over time, potentially exhausting system RAM** -> **Always call `delete` or `delete[]` when heap allocations are no longer needed (252:00)** * **Calling `delete` multiple times on the same pointer (double-free)** -> **Runtime program crash or memory manager corruption** -> **Set pointers to `nullptr` immediately after deallocation (158:00)** * **Using standard `delete` instead of `delete[]` for dynamic arrays** -> **Undefined behavior, memory leak, or destructor skipping** -> **Always use `delete[]` when freeing memory allocated with `new[]` (297:00)**

๐Ÿ“Ž Repo Files

  • 11.Loops/11.11DecrementingLoops/main.cpp
  • 12.Arrays/12.2DeclaringAndUsingArrays/main.cpp
  • 12.Arrays/12.3SizeOfAnArray/main.cpp
  • 12.Arrays/12.4ArraysOfCharacters/main.cpp
  • 12.Arrays/12.5ArrayBounds/main.cpp
  • 12.Arrays/12.8MultiDimensionalArrays/main.cpp