A pointer stores an address
A pointer is an object whose value can identify another object or function. It is not the object itself. Before dereferencing a pointer, you must know what it points to, whether that object is still alive, and whether the access is permitted for its type.
Address-of and dereference
#include
int main(void) {
int score = 40;
int *p = &score;
printf("before=%d\n", *p);
*p = 45;
printf("after=%d\n", score);
printf("address=%p\n", (void *)p);
return 0;
} The first two output lines are before=40 and after=45. The actual address varies between executions and environments. The conversion %p expects a void pointer, so this example explicitly converts p. Do not print an address with an integer format such as %d.
In the declaration int *p, the star is part of the declarator. In the expression *p, it dereferences a pointer. The ampersand in &score obtains an address. These are different roles, even though the same symbols have other meanings in arithmetic expressions.
Three unsafe pointer states
- Uninitialized: a local pointer declared without an initializer does not automatically point anywhere valid.
- Null: NULL represents no target object. Test it before use when an interface can return it; never dereference it.
- Dangling: the target's lifetime has ended, for example after free or after returning from a function with an automatic local.
Setting one pointer to NULL after freeing storage does not repair other pointers that held the same address. Ownership must be clear.
const with pointers
const int *p lets you change p but not the int through p. int *const p = &score; fixes the pointer value but permits changing score through it. const int *const p = &score; restricts both through that name. Read the declaration in terms of what is allowed to change.
Declaration trap
int *a, b; declares one pointer and one ordinary int. Use separate declarations when this notation could confuse a reader. A pointer's size is not the size of the object it points to; sizeof p and sizeof *p answer different questions.
Exercises
- Use a pointer to multiply a variable by two. Starting at 12 should leave the target at 24.
- Draw the relationship between score, p and &score.
- Why is returning
&localfrom a function unsafe? The automatic local stops existing when the function returns. - Write a function that accepts
const int *and only reads the value. State that a valid object address is required.