C Pointers: Memory Addresses and Variable Handling
Understanding Pointers in C
A pointer represents a memory address location. Two key aspects define pointers:
- A pointer is the numerical identifier of the smallest memory unit (address)
- Commonly, "pointer" refers to a pointer variable that stores memory addresses
In essence, pointers are memory addresses, while pointer variables are containers for those addresses.
Memory Addressing Fundamentals
#include <stdio.h>
int main() {
int value = 42;
int *addr_container = &value;
return 0;
}
Pointer variables store memory locations. Key considerations:
- Smallest addressable unit: 1 byte
- 32-bit systems use 4-byte pointers (4GB address space)
- 64-bit systems use 8-byte pointers (16 exabytes address space)
Pointer Types and Operations
Pointer types determine behavior during arithmetic operations and dereferencing:
int main() {
int data = 0x11223344;
char *byte_ptr = (char *)&data;
int *int_ptr = &data;
*byte_ptr = 0; // Modifies one byte
*int_ptr = 0; // Modifies four bytes
return 0;
}
Pointer arithmetic behavior:
int main() {
int num = 100;
char *c_ptr = (char*)#
int *i_ptr = #
printf("%p\n", &num);
printf("%p\n", c_ptr);
printf("%p\n", c_ptr + 1); // Advances 1 byte
printf("%p\n", i_ptr + 1); // Advances 4 bytes
return 0;
}
Wild Pointers and Prevention
Wild pointers reference undefined memory locations. Common causes:
- Uninitialized pointers
- Out-of-bounds access
- References to freed memory
Prevention techniques:
int main() {
int *ptr = NULL;
int x = 50;
ptr = &x;
if(ptr != NULL) {
*ptr = 60;
}
return 0;
}
Pointer Arithmetic Applications
Common pointer operations:
// Array traversal
float measurements[5];
float *measure_ptr;
for (measure_ptr = &measurements[0];
measure_ptr < &measurements[5];) {
*measure_ptr++ = 0.0;
}
// String length calculation
int str_length(char *str) {
char *start = str;
while(*start != '\0') start++;
return start - str;
}
Pointers and Arrrays
Array names typically represent their first element's address:
int main() {
int sequence[] = {10, 20, 30, 40};
int *seq_ptr = sequence;
size_t count = sizeof(sequence)/sizeof(sequence[0]);
for(size_t i = 0; i < count; i++) {
printf("%d ", *(seq_ptr + i));
}
return 0;
}
Multi-level Pointers
Pointers to pointers enable additional indirection:
int main() {
int base = 100;
int *first_ptr = &base;
int **second_ptr = &first_ptr;
**second_ptr = 200; // Modifies base
return 0;
}
Pointer Arrays
Arrays can store pointer values:
int main() {
int x = 5, y = 10, z = 15;
int *ptr_array[3] = {&x, &y, &z};
for(int i = 0; i < 3; i++) {
printf("%d\n", *ptr_array[i]);
}
return 0;
}