> For the complete documentation index, see [llms.txt](https://cs.d19.in/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cs.d19.in/pointers.md).

# Pointers

## **What is a Pointer?**

A pointer is a variable that **stores the address** of another variable. Instead of holding a data value, a pointer holds the location of that value in memory.

**Pointer Basics**

* **Declaration:** You declare a pointer by specifying the type of data it points to, followed by an asterisk `*`.

  ```c
  int *ptr;  // Pointer to an integer
  ```
* **Initialization:** You assign a pointer the address of a variable using the address-of operator `&`.

  ```c
  int x = 10;
  int *ptr = &x;  // 'ptr' now holds the address of 'x'
  ```
* **Dereferencing:** To access the value stored at the address a pointer points to, you use the dereference operator `*`.

  ```c
  int value = *ptr;  // Retrieves the value at the address stored in 'ptr'
  ```

***

#### **Pointer Example**

Here’s a simple example showing how pointers work:

```c
#include <stdio.h>

int main() {
    int x = 10;         // Regular integer variable
    int *ptr = &x;      // Pointer variable that holds the address of 'x'
    
    printf("Value of x: %d\n", x);        // Outputs: Value of x: 10
    printf("Address of x: %p\n", &x);    // Outputs the memory address of 'x'
    printf("Value of ptr: %p\n", ptr);   // Outputs the address stored in 'ptr'
    printf("Value pointed to by ptr: %d\n", *ptr);  // Outputs: Value pointed to by ptr: 10
    
    return 0;
}
```

**Explanation:**

* `int *ptr = &x;` initializes the pointer `ptr` with the address of `x`.
* `*ptr` is used to access the value of `x` through the pointer.

***

#### **Pointer Arithmetic**

Pointers can be incremented or decremented to point to different memory locations. This is especially useful with arrays.

**Example: Pointer Arithmetic with Arrays**

```c
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30};
    int *ptr = arr;  // Pointer to the first element of the array
    
    printf("First element: %d\n", *ptr);         // Outputs: 10
    printf("Second element: %d\n", *(ptr + 1));  // Outputs: 20
    printf("Third element: %d\n", *(ptr + 2));   // Outputs: 30
    
    return 0;
}
```

**Explanation:**

* `ptr + 1` moves the pointer to the next integer (4 bytes away in most systems).
* `*(ptr + 1)` accesses the second element of the array.

***

#### **Dynamic Memory Allocation**

Pointers are used to allocate memory dynamically at runtime using functions from the `<stdlib.h>` library.

**Functions:**

* **`malloc(size_t size)`**: Allocates memory.
* **`free(void *ptr)`**: Frees allocated memory.
* **`calloc(size_t num, size_t size)`**: Allocates memory and initializes it to zero.
* **`realloc(void *ptr, size_t newSize)`**: Resizes previously allocated memory.

**Example: Using `malloc` and `free`**

```c
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = (int *)malloc(3 * sizeof(int));  // Allocate memory for 3 integers
    
    if (arr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }
    
    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;
    
    printf("First element: %d\n", arr[0]);   // Outputs: 10
    printf("Second element: %d\n", arr[1]);  // Outputs: 20
    printf("Third element: %d\n", arr[2]);   // Outputs: 30
    
    free(arr);  // Free the allocated memory
    
    return 0;
}
```

**Explanation:**

* `malloc` allocates memory on the heap.
* Always check if `malloc` returns `NULL` to handle memory allocation failures.
* `free` releases the allocated memory to avoid memory leaks.

***

#### **Pointers and Functions**

Pointers can be passed to functions to allow modifications to the original data or to handle large amounts of data efficiently.

**Example: Modifying Data Using Pointers**

```c
#include <stdio.h>

void increment(int *p) {
    (*p)++;  // Increment the value pointed to by 'p'
}

int main() {
    int num = 5;
    increment(&num);  // Pass the address of 'num'
    printf("Incremented value: %d\n", num);  // Outputs: Incremented value: 6
    return 0;
}
```

**Explanation:**

* `increment(&num)` passes the address of `num` to the function.
* `(*p)++` modifies the value of `num` through the pointer.

***

#### **Pointers to Pointers**

A pointer to a pointer is a variable that stores the address of another pointer.

**Example:**

```c
#include <stdio.h>

int main() {
    int x = 10;
    int *ptr = &x;
    int **pptr = &ptr;
    
    printf("Value of x: %d\n", x);                // Outputs: 10
    printf("Value pointed to by ptr: %d\n", *ptr); // Outputs: 10
    printf("Value pointed to by pptr: %d\n", **pptr); // Outputs: 10
    
    return 0;
}
```

**Explanation:**

* `ptr` is a pointer to `x`.
* `pptr` is a pointer to `ptr`.

***

#### **Summary**

* **Pointers** store addresses of variables.
* **Dereferencing** `*` accesses the value at the pointer’s address.
* **Pointer Arithmetic** allows moving through arrays.
* **Dynamic Memory Allocation** uses `malloc`, `calloc`, `realloc`, and `free`.
* **Pointers in Functions** enable modifications to original data.
* **Pointers to Pointers** involve multiple levels of indirection.
