windowsmemoryprocess

Question about the NULL-Pointer Assignment Partition in a process' address space


I am reading < Windows via C/C++ 5th edition > and below is some quotation:

Each process' virtual address space is split into partitions. On x86 32-Bit Windows, the partition of 0x00000000 - 0x0000FFFF (inclusive) is called NULL-Pointer Assignment Partition. This partition is set aside to help programmers catch NULL-pointer assignments. If a thread in your aprocess attempts to read from or write to a memory address in this partition, an access violoation is raised.

I am wondering, why do we have to use a range of address space instead of just the value 0 to catch NULL-pointer assignments? AFAIK, NULL equals 0. So what's the consideration behind this design? Is there anything else reside in this range that user shouldn't touch? Or does NULL not necessarily equal 0?

Many thanks.


Solution

  • All modern operating systems cleverly implement a null pointer dereference check with no execution overhead using the virtual memory management hardware. The 0th 4 KB page (or in this case, 0-15th pages (totalling 64 KB)) is set up so any data read or write or instruction execution at address 0 (or 0x00000FFF or 0x0000FFFF for that matter) instantly results in an access violation exception.

    Let me put it a different way. Trapping null pointer dereferences to 0, but allowing data references to (say) address 1, would be prohibitively expensive -- since you could not use the page-granularity VM hardware, it would instead be necessary to perform a null pointer compare and branch sequence before many pointer dereferences. By making the first page or first few pages inaccessible, this check can be done "for free" in the VM hardware. The downside is you can't use those first page(s) for anything else.

    (In theory, a sufficiently optimizing compiler could then be employed to determine which pointer dereferences could not possibly be null pointer dereferences, but until such clever compilers appear, the unmapped 0 page trick will have to do.)

    So why is the Windows (post Win98) null pointer assignment partition 64 KB instead of the minimum necessary 4 KB? Wyzard's answer makes a good case for catching null pointer array index errors as well.

    *** Late update: RE: why 64 KB? -- I asked someone who ought to know on the Windows Core team, and they said it is probably a 64 KB region because Windows keeps certain memory management structures at a 64 KB allocation granularity. Why is that? I don't know, but perhaps Raymond Chen has the answer: https://devblogs.microsoft.com/oldnewthing/20031008-00/?p=42223. Wow. ***