-1

I had a query regarding one of the answers of this question.

The answer says:

If a 32-bit processor can address 2^32 memory locations, that simply means that a C pointer on that architecture can refer to 2^32 - 1 locations plus NULL

Isn't it 2^32 plus NULL? Why is the -1?

EDIT: sorry for not being clear. Edited question.

Community
  • 1
  • 1
Nemo
  • 4,601
  • 11
  • 43
  • 46

5 Answers5

2

2^32 - 1 locations plus NULL

That equals 2^32.

In most programming languages and operating systems NULL is a dedicated pointer value (usually 0) that means invalid pointer, thats why it cannot be used to point a valid memory location.

Because pointers are just like any integer numbers, there's no other way to signal invalid pointer than with a dedicated value. Because 32 bit integers can have 2^32 possible values, if you don't count this NULL value, you get 2^32-1 valid memory locations.

buc
  • 6,268
  • 1
  • 34
  • 51
1

The author of that text is distinguishing NULL as not being a memory location. So you use one of the 2^32 available values for NULL which leaves 2^32-1 available for memory locations.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

NULL is actually a value, usually 0, so if you add it you get 2^32

Daniel Shaulov
  • 2,354
  • 2
  • 16
  • 25
0

I believe the concept of NULL originally comes from memory allocators when they have failed at allocating a slot of memory. By comparing the returned value with NULL the programmer can determine whether the pointer may be used as such or not. I don't believe that NULL has any place in the discussion, it is simply a form of alias for position 0 (0x00000000).

In real-mode (lacking a memory protection scheme) systems the memory at location 0 may usually be read from and sometimes written to (if it isn't read-only). This of course depends on if physical memory chips are actually wired to that location. In many real-mode systems with a writable 0 location you get funny results if you manipulate that location. In x86 (16-bit real mode) PC-DOS systems the location points to the first vector in the interrupt vector table, a vector that points to the interrupt handler for divide by 0. A programmer could write there by mistake or for some valid reason.

In protected-mode systems a program accessing the 0 position will usually cause a memory protection fault that will terminate it. I should clarify this and say that location 0 to the application is almost certainly not the physical location 0 since most protected mode OSes have remapped an application's memory area using a virtual addressing mechanism provided by the host processor. The OS itself may, under certain circumstances, give itself or another program permission to access whatever memory location it pleases but such circumstances are few and so restricted that an application developer will never encounter them in his or her lifetime.

With this somewhat lengthy backgrounder I agree with those who say that for a 32-bit processor there are usually 2^32 addressable locations ranging from 0 (0x00000000) to 2^32-1 (0xffffffff). Exceptions are early 32-bit processors (such as intel's 486sx and Motorola's 68000) that implemented less than 32 adressing lines.

Olof Forshell
  • 3,169
  • 22
  • 28
0

The author is saying that the C implementation must reserve one of the addresses that the processor can use, so that in C that address is used to represent a null pointer. Hence, C can address one fewer memory locations than the processor can. Convention is to use address 0 for null pointers.

In practice, a 32-bit processor can't really address 2^32 memory locations anyway, since various parts of the address space will be reserved for special purposes rather than mapped to memory.

There's also no actual requirement that the C implementation represent pointers using the same sized addresses that the processor uses. It might be horribly inefficient to do so, but the C implementation could use 33-bit pointers (which would therefore require at least 5 bytes of storage, and wouldn't fit in a CPU register), enabling it to use a value for null pointers that isn't one of the 2^32 addresses the processor can handle.

But assuming nothing like that, it's true that a 32 bit pointer can represent any of 2^32 addresses (whether those addresses refer to memory locations is another matter), and it's also true that since C requires a null pointer, one of those addresses must be used to mean "a null pointer".

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699