In the C language, pointers and dereferencing operations are fundamental to manual memory management and low-level programming. The address-of operator (&) returns the address of a variable in memory, creating a pointer. The dereference operator (*) allows access to the value pointed to by a pointer. These tools enable the implementation of complex data structures, memory management, passing large objects by address, and direct interaction with hardware.
History of the question
The emergence of pointers and these operators was a necessary step to provide programmers with the ability to work directly with memory, ensuring efficiency and flexibility in writing system-level applications and drivers.
Problem
Constant manual memory management and explicit dereferencing can easily lead to errors: for example, accessing freed memory, incorrect types, loss of access to allocated areas, and uncontrolled memory leaks.
Solution
Proper and careful use of the operators * and &, strict adherence to types, understanding the differences between pointers of different types, and following rules of scope and lifetime of data.
Example code:
#include <stdio.h> void increment(int *p) { (*p)++; } int main() { int x = 10; int *ptr = &x; increment(ptr); // x will increase to 11 printf("%d\n", x); // output: 11 return 0; }
Key features:
Can dereferencing an arbitrary pointer cause a segmentation fault?
Yes, if dereferencing an incorrect or uninitialized pointer, the program will terminate with an exception. For example:
int *a = NULL; printf("%d", *a); // Segmentation fault
What happens if you take the address of a temporary value (e.g., the result of an expression)?
In C, you cannot take the address of a temporary result of an arithmetic expression directly, only the address of a variable:
int x = 5; int *p = &(x + 1); // Compilation error
Can you dereference void?*
No, you cannot. The void* pointer is universal, but it must be cast to a specific type before dereferencing:
void* p = ...; int val = *(int*)p; // First cast, then dereference
A junior developer freed memory using free(ptr), but then mistakenly tried to access *ptr, causing the application to crash.
Pros:
Cons:
An experienced developer always nullifies the pointer after freeing memory: free(ptr); ptr = NULL;. Before dereferencing, they always check for NULL.
Pros:
Cons: