How pointers in C/C++ actually store addresses?

Viewed 940

If an int is stored in memory in 4 bytes each if which having a unique address, which address of these four addresses does a pointer to that int store?

5 Answers

A pointer to int (a int*) stores the address of the first byte of the integer. The size of int is known to the compiler, so it just needs to know where it starts. How the bytes of the int are interpreted depends on the endianness of your machine, but that doesn't change the fact that the pointer just stores the starting address (the endianness is also known to the compiler).

Those 4 int bytes are not stored in the random locations - they are consecutive. So it is enough to store the reference (address) of first byte of the object.

Depends on the architecture. On a big-endian architecture (M68K, IBM z series), it’s usually the address of the most significant byte. On a little-endian architecture (x86), it’s usually the address of the least-significant byte:

 A   A+1 A+2 A+3    big-endian
+–––+–––+–––+–––+
|msb|   |   |lsb|
+–––+–––+–––+–––+
 A+3 A+2 A+1 A      little-endian

There may be other oddball addressing schemes I’m leaving out.

But basically it’s whatever the underlying architecture considers the “first” byte of the word.

If an int is stored in memory in 4 bytes which each has a unique address, which address of these four addresses does a Pointer to that int store?

A pointer to int usually stores the address value of the first byte (which is stored at the lowest memory address) of the int object.

Hence the size of the int is known and constant at a specific implementation/ architecture and an int object is always stored in consecutive bytes (there are no bytes between two of them), it is clear that the following ((if sizeof(int) == 4) three) bytes belong to the same int object.

How the bytes of the int object are interpreted is dependent upon Endianness*.

The first byte is usually automatically aligned on a multiple of the data word size dependent upon a specific architecture, so that the CPU can work most efficiently.

In a 32-bit architecture for example, when the data word size is 4, the first byte lies on a 4-byte boundary - an address location with a multiple of 4.

sizeof(int) is not always 4 (although common) by the way.


*Endianness can influence if the interpretation of the object starts at the most (the first) or least (the last) significant byte.

The C Standard does not specify how addresses are represented inside pointers. Yet on most current architectures, a pointer to an int stores its address as the offset in the process' memory space of the first byte of memory used to store it, more precisely the byte with the lowest address.

Note however these remarks:

  • the int may have more or fewer than 32 bits. The only constraint is it must have at least 15 value bits and a sign bit.
  • bytes may have more than 8 bits. Most current architectures use 8-bit bytes but early Unix systems had 9-bit bytes, and some DSP systems have 16-, 24- or even 32-bit bytes.
  • when an int is stored using multiple bytes, it is unspecified how its bits are split among these bytes. Many systems use little-endian representation where the least-significant bits are in the first byte, other systems use big-endian representation where the most significant bits and the sign bit are in the first byte. Other representations are possible but only in theory.
  • many systems require that the address of the int be aligned on a multiple of their size.
  • how pointers are stored in memory is also system specific and unspecified. Addresses do not necessarily represent offsets in memory, real of virtual. For example 64-bit pointers on x86 CPUs have a number of bits that can be ignored or that may contain a cryptographic signature verified on the fly by the CPU. Adding one to the stored value of a pointer does not necessarily produce a valid pointer.
Related