Unit content
Pointers, addresses and object lifetimes in C
A pointer is a C value that can refer to an object or function through its address.
Taking and using addresses
The address-of operator & obtains the address of an object, while unary * dereferences a pointer:
int x = 10;
int *p = &x;
*p = 12;
After the assignment through p, x contains 12 because both expressions designate the same object.
Pointer types
A pointer carries a type such as int * or double *. The pointed-to type determines how dereferencing and pointer arithmetic are interpreted.
A null pointer represents the absence of a valid target and must not be dereferenced.
Arrays and pointer arithmetic
In many expressions an array is converted to a pointer to its first element. If p points to an array element, p + 1 points to the next element, not merely one byte later.
For an array
int a[4] = {3, 6, 9, 12};
a[i] is closely related to *(a + i).
This relationship explains why C APIs often pass an address together with an explicit element count.
Pointers are not ownership
A pointer says where an object can be found; by itself it does not say who owns that object, how long the object remains valid, or who is responsible for releasing storage.
Object lifetime
Automatic local objects normally cease to exist when execution leaves their block. Returning a pointer to such an expired object produces a dangling pointer.
int *bad(void) {
int x = 4;
return &x; /* x's lifetime ends on return */
}
Static-storage objects live for the program's execution. Dynamically allocated objects have a lifetime controlled explicitly by allocation and deallocation operations.
Memory safety
Invalid dereferences can arise from
- null pointers;
- dangling pointers;
- out-of-bounds pointer arithmetic;
- using storage after its lifetime has ended;
- interpreting storage through incompatible types.
Pointers are therefore the bridge between C's language-level objects and the machine's addressable memory. Understanding them is necessary before dynamic allocation can be treated coherently.