Pointers Store Addresses — So Why Do They Have Types?
Source: Dev.to
Why pointers have types
We often hear that a pointer is just a variable that stores a memory address.
That statement is technically true, but incomplete. If pointers were only raw addresses, every pointer would be identical (typically 4 or 8 bytes). In C/C++ we have char*, int*, double*, struct*, and so on.
If the address is just a number, why does the type matter?
The role of the pointer type
Physical memory does not distinguish between an integer, a character, or a floating‑point number; it is simply a sequence of bytes. The pointer type acts as a template for the compiler, telling it two critical things:
- Width – how many bytes to read starting from that address.
- Interpretation – once those bytes are fetched, how to treat them (e.g., as a signed integer, an IEEE‑754 float, or an ASCII character).
Example visualization
Consider four bytes of memory starting at address 0x20000000:
| Address | Value |
|---|---|
0x20000000 | 0x01 |
0x20000001 | 0x02 |
0x20000002 | 0x03 |
0x20000003 | 0x04 |
Dereferencing a char*
char *pc = (char *)0x20000000;
char c = *pc; // reads 1 byte
The compiler reads exactly one byte (0x01) and treats it as a character.
Dereferencing an int*
int *pi = (int *)0x20000000;
int i = *pi; // reads 4 bytes
The compiler reads the next four bytes and combines them into an integer, yielding 0x04030201 on a little‑endian system.
The address and the underlying data are unchanged; only the interpretation differs.
Fundamental truths about memory and pointers
- Memory is a linear address space of byte‑sized storage units.
- An address is merely a starting point.
- Pointer types tell the compiler how to interpret the bytes at that address.
Because memory itself has no notion of types, the pointer type becomes critical. It informs the compiler:
- How many bytes to read or write.
- How to interpret those bytes.
- How pointer arithmetic should behave.
Pointer arithmetic and type scaling
Pointer arithmetic is scaled by the size of the pointed‑to type. For example:
int *p;
p = /* some address */;
p + 1; // advances 4 bytes, because sizeof(int) == 4
If p were a char*, p + 1 would advance only one byte.
Understanding that “a pointer stores an address” is only the first step. Grasping pointer types reveals how software actually talks to memory.