0

In many C implementations (but not all), NULL corresponds to a process's logical address 0. When we try to dereference NULL, we get a segmentation fault because NULL "maps" to a memory segment that is neither readable nor writable.

Are there systems with real, physical addresses that correspond to the virtual NULL address? If so, what might be stored there? Or is NULL purely a virtual address with no physical counterpart?

kaerimasu
  • 690
  • 3
  • 17
  • 2
    Possible duplicate of [What happens in OS when we dereference a NULL pointer in C?](http://stackoverflow.com/questions/12645647/what-happens-in-os-when-we-dereference-a-null-pointer-in-c) – Fred Larson Mar 28 '16 at 14:45
  • Well yes, of course there is a physical address 0: It's the first byte on the first RAM stick for some definition of "first". On some CPUs, the pointers to the interrupt service routines that the CPU invokes on an exception are stored in the first few bytes of memory. – Iwillnotexist Idonotexist Mar 28 '16 at 14:45
  • Also see http://stackoverflow.com/questions/2960496/why-is-null-0-an-illegal-memory-location-for-an-object – ypnos Mar 28 '16 at 14:46
  • 2
    A null pointer is a concept, `NULL` is the implementations (compilers) realization of the concept. It's true that on many platforms the null pointer is represented by the address `0` (as in `(void *) 0`) but that implementation-specific part should be of no concern. From your point of view as a programmer, a null pointer is a null pointer and that's it. – Some programmer dude Mar 28 '16 at 14:47
  • 3
    Dereferencing NULL does not necessarily lead to a crash, it is undefined behavior. Nasal demons. Not all systems that can use C have a concept similar to a segmentation fault. – Fred Larson Mar 28 '16 at 14:47
  • 1
    @IwillnotexistIdonotexist, physical address 0 does not necessarily correspond to a process's virtual address 0. – kaerimasu Mar 28 '16 at 14:47
  • @JoachimPileborg, the question isn't really about NULL being 0. It's about whether there's a physical address that corresponds to the NULL pointer, whatever it may be. This is a question of implementation. – kaerimasu Mar 28 '16 at 14:49
  • @kaerimasu I know this very well; I'm speaking to you of physical memory because you understand very well virtual memory by all appearances. And it so happens that many CPUs/microcontrollers. store their interrupt vectors in the first few bytes of physical memory (and the OS then makes sure never to map a userland process's NULL page to physical 0, for fear of trashing this critically important table) – Iwillnotexist Idonotexist Mar 28 '16 at 14:49
  • 2
    `NULL` may or may not have a corresponding physical address. It's valid per C standard in either case. What C standard says is that it's *undefined* to dereference NULL. So the answer to (many of) your question is "it depends". – P.P Mar 28 '16 at 14:50
  • 1
    From your *source code's* point of view, `NULL` is a well-defined "nowhere"; it's an *invalid* address value guaranteed to compare unequal to the address of any object or function in your program. It is not coupled to a specifc physical address, and it's a mistake to think of it in those terms. It may be helpful to think of it more in RDBMS terms where `NULL` isn't a value in and of itself; rather, it is a *lack* of a value. – John Bode Mar 28 '16 at 15:01
  • 2
    @John Bode I think OP is looking for some defined properties of `NULL` beyond the C spec. `NULL` may be an invalid address. `NULL` may be an valid address. `NULL` may/may not not be coupled to a specific physical address. Certainly agree it is "guaranteed to compare unequal to the address of any object or function in your program." – chux - Reinstate Monica Mar 28 '16 at 15:30

5 Answers5

1

NULL is implementation defined.

It is a macro which expands to an implementation defined null pointer constant.

"it depends" @I3x

Is there a real, physical address that corresponds to the virtual NULL address?

On some platforms: yes, on others: no. It is implementation defined.

If so, what might be stored there?

On some platforms: a value, maybe 0. This value may/may not be accessible. On others: there is simple no access. It is implementation defined.

Or is NULL purely a virtual address with no physical counterpart?

On some platforms: it is a virtual address with no counterpart. On others it may be a real address. It is implementation defined.

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • The fact that the `NULL` macro is implementation-defined is not particularly relevant. It allows the implementation to define it as `0`, or as `((void*)0`, or as `('-'-'-')`, but however it's defined it yields a *null pointer* when converted to a pointer type. – Keith Thompson Mar 28 '16 at 16:01
  • 1
    @ Keith Thompson The detail about being a macro stems from how the C spec defines it - so it makes sense to start with the C definition. It is a tricky part about `NULL`: it may not result in a _pointer_. It results in a _null pointer constant_. As you say, when `NULL` is converted to a pointer, it is a _null pointer_. – chux - Reinstate Monica Mar 28 '16 at 16:35
1

From C-standard paper ISO/IEC 9899:201x (C11) §6.3.2.3 Pointers:

  1. An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function

This means that a NULL pointer should give a result TRUE if compared to a 0 value, and also that it will resolve to a value=0 if converted to an arithmetic type.
But it also mean that the compiler must generate a value for the null pointer that is guaranteed not to be an address existing (compare equal) in the code running environment (this should be more standardish).
The scope is to make the code portable imposing that each operation on NULL pointer must give same result on any CPU or architecture.

Note: on practical side to guarantee that the NULL pointer doesn't equals any address in the running environment there are two ways. The first will apply to those platforms where invalid address exists, getting advantage of such invalid addresses. The second is to conventionally reserve an address for the scope, typically 0. The latter means that the platform, the OS mainly, have to take care to make that address invalid in the sense that it isn't usable and then can never equal any other pointer, else there will always be an object that can legally use that address and consequently make valid its address comparison to the NULL pointer. This point is important because missing any infrastructure, as an OS could be, that takes care of the invalid value we can have a conflicting condition. An example is when using C compiler for base programming, OS and kernel, if the processor use the memory from address 0 to hold interrupt service addresses a pointer to the object will have a value of 0. In this case the compiler should use a different value of NULL pointer, but if the OS can access the whole addressing space. to allow full Memory Management, there will be no value applicable for NULL pointer.
On user or kernel HL code this is not a problem because there arealways some addresses that are normally not allowed and can then be used for the NULL pointer value.

Frankie_C
  • 4,764
  • 1
  • 13
  • 30
  • 2
    There's no requirement for a null pointer to be an invalid address for the target system. It merely must compare unequal to a pointer to any object or function. For example, there are systems were *all* addresses are valid as far as the CPU is concerned; the implementation merely has to avoid allocating anything to the address referred to by the null pointer. Dereferencing a null pointer has undefined behavior; it needn't cause any kind of trap. – Keith Thompson Mar 28 '16 at 15:57
1

Yes, most (all?) systems have a real physical address zero, it is just inaccessible from a process running behind a virtual address-space which remaps virtual addresses to (different) physical addresses. In those processes the address zero is simply left unmapped to anything, just as most of the rest of their address space.

However, as a matter of fact, all the x86 based processors till this day boot into the 'real mode' at first. This is a 8086 compatibility mode. Under this processor mode, not only there is a physical addressable address zero, but this address is actually where the interrupt vector table located at, and this is where the processor reads from when it handles interrupts.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
0

Certainly on some computers, there is actual memory at address 0. On others, there may not be. There are even some hardware designs for which the answer may depend on the temporary state of a memory-mapping chip or chipset.

But in all cases, dereferencing a NULL pointer is undefined behavior.

Logicrat
  • 4,438
  • 16
  • 22
-1

In many C implementations (but not all), NULL corresponds to a process's logical address 0.

No, that is the wrong way to look at it. Null pointers do not correspond to anything other than themselves, by definition, and C in no way ties null pointers to any particular address, in any sense of the term.

At best, you could say that some implementations' representations of null pointers have the form that a representation of a pointer to an object residing at machine address 0 would have. Since null pointers compare unequal to every pointer to an object or function, however, such a situation requires that it be impossible for any object or function that the C program can reference to reside at that address.

When we try to dereference NULL, we get a segmentation fault

That is one of the multitude of observed behaviors that are possible when you invoke undefined behavior. Empirically, it is one of the more likely to be observed when undefined behavior is invoked in the particular way you describe. It is by no means guaranteed by C, and indeed, there are widely-used implementations which, empirically, exhibit different behavior.

because NULL "maps" to a memory segment that is neither readable nor writable.

But there you're delving deep into implementation details.

Is there a real, physical address that corresponds to the virtual NULL address?

No, because a null pointer is not an address. It is a pointer value that is explicitly invalid to dereference. Technically, although C refers to some pointer values as "addresses", it neither requires nor depends on any pointer value to be a machine address, neither a physical nor a virtual one. The value of a null pointer, however, is not an address even in C's sense of the term. The & operator never produces this value, and it is invalid to dereference -- it explicitly fails to correspond to any object or function.

If so, what might be stored there? Or is NULL purely a virtual address with no physical counterpart?

Although it is indeed common for null pointer values to be represented in the way that a pointer to an object / function residing at machine address 0 would be, this is irrelevant, because in that case a C program can never access anything residing at that address. Thus, as far as the program is concerned, nothing resides there. As far as the hardware and OS kernel are concerned, on the other hand, external programs' view of memory is largely irrelevant. And if one nevertheless insists on considering the kernel's view of what is stored in physical memory at an address derived from an external program's null pointer representation, it is highly system-dependent.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • "Technically, **no** pointer value is an address *per se* as far as C is concerned ...". Actually, *all* valid non-null pointer values are "addresses" as far as C is concerned. But an "address" isn't necessarily the same thing as a "machine address". For example the C standard says "The unary **`&`** operator yields the address of its operand." – Keith Thompson Mar 28 '16 at 16:00
  • The question was explicitly about possible implementations. – kaerimasu Mar 29 '16 at 00:50
  • @KeithThompson, your observation and the distinction you draw about different kinds of addresses are well taken. I contend, however, that even so, C says only that addresses exist, in some sense, and that these are pointer values, *not* that all pointer values are addresses in this sense. Certainly, the definition of pointer types avoids the word "address". I have rewritten my answer to be more precise. – John Bollinger Mar 30 '16 at 14:19