C Pointers and Memory Management

Master one of C's most powerful features - pointers, memory allocation, and dynamic memory management.

What are Pointers?

A pointer is a variable that stores the memory address of another variable. Think of it as a "reference" or "address" that points to where data is stored in memory.

Key concepts:
- Pointers store memory addresses, not the actual data
- Every variable has a memory address
- Pointers allow direct access to memory locations
- They enable dynamic memory allocation and efficient data manipulation

Basic syntax:
```c
int *ptr;        // Declaration of a pointer to int
int value = 42;  // Regular integer variable
ptr = &value;    // ptr now points to the address of value
```

Pointer Declaration and Initialization

Pointers must be declared with the correct data type they will point to.

Declaration syntax:
```c
int *ptr1;           // Pointer to int
char *ptr2;          // Pointer to char
float *ptr3;         // Pointer to float
double *ptr4;        // Pointer to double
```

Initialization:
```c
int x = 10;
int *ptr = &x;       // ptr points to the address of x
```

Important notes:
- Always initialize pointers before use
- Uninitialized pointers contain garbage values
- Use NULL to represent a pointer that doesn't point anywhere

Address and Dereference Operators

Two essential operators for working with pointers:

1. Address Operator (&):
   - Returns the memory address of a variable
   - Used to get the address to assign to a pointer

2. Dereference Operator (*):
   - Accesses the value at the address stored in a pointer
   - Used to read or modify the value being pointed to

Example:
```c
int x = 42;
int *ptr = &x;       // &x gives the address of x

printf("Value of x: %d\n", x);        // 42
printf("Address of x: %p\n", &x);     // Memory address
printf("Value via pointer: %d\n", *ptr); // 42 (dereferencing)

*ptr = 100;          // Changes x to 100 through the pointer
printf("New value of x: %d\n", x);    // 100
```

Pointer Arithmetic

Pointers support arithmetic operations, but they work differently than regular arithmetic.

Pointer arithmetic rules:
- Adding/subtracting integers moves the pointer by that many elements
- The size of movement depends on the data type
- Only addition, subtraction, and comparison are meaningful

Example:
```c
int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;      // Points to first element

printf("%d\n", *ptr);        // 10
ptr++;                       // Move to next element
printf("%d\n", *ptr);        // 20
ptr += 2;                    // Move 2 elements forward
printf("%d\n", *ptr);        // 40
```

Dynamic Memory Allocation

Pointers enable dynamic memory allocation - creating memory at runtime.

Key functions:
- malloc(): Allocates memory
- calloc(): Allocates and initializes memory to zero
- realloc(): Resizes previously allocated memory
- free(): Deallocates memory

Example:
```c
#include <stdlib.h>

int *ptr = malloc(5 * sizeof(int));  // Allocate array of 5 integers
if (ptr == NULL) {
    printf("Memory allocation failed\n");
    return 1;
}

// Use the allocated memory
for (int i = 0; i < 5; i++) {
    ptr[i] = i * 10;
}

// Don't forget to free the memory!
free(ptr);
ptr = NULL;  // Good practice
```

Practice Examples

Try these examples in our online C compiler to reinforce your learning:

Basic Pointer Operations

Demonstrates basic pointer declaration, initialization, and dereferencing.

#include <stdio.h>

int main() {
    int num = 42;
    int *ptr = &num;
    
    printf("Value of num: %d\n", num);
    printf("Address of num: %p\n", &num);
    printf("Value via pointer: %d\n", *ptr);
    printf("Address stored in pointer: %p\n", ptr);
    
    // Modify value through pointer
    *ptr = 100;
    printf("New value of num: %d\n", num);
    
    return 0;
}

Array and Pointer Relationship

Shows how arrays and pointers are closely related in C.

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;  // Same as &arr[0]
    
    printf("Array elements using pointer arithmetic:\n");
    for (int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, *(ptr + i));
    }
    
    printf("\nArray elements using array notation:\n");
    for (int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }
    
    return 0;
}

Dynamic Array Allocation

Creates a dynamic array using malloc() and demonstrates proper memory management.

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

int main() {
    int n;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    
    // Allocate memory dynamically
    int *arr = malloc(n * sizeof(int));
    if (arr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }
    
    // Input elements
    printf("Enter %d elements:\n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    
    // Display elements
    printf("Array elements: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    // Free allocated memory
    free(arr);
    
    return 0;
}

Ready for the Next Step?

Continue your C programming journey with our next tutorial.

Next: C Functions →