views:

165

answers:

7

I know there's an old saying when you want to indicate this specific pointer doesn't point to anything it should be set to NULL(actually 0), but I'm wondering isn't there actually a physical part of memory with the address of NULL(0) ?

+1  A: 

Unless you write a system kernel, from your point of view there is no such memory location. Your addresses are in virtual address-space, that mean they are not physical. They are translated to physical by the CPU looking up system tables.

ybungalobill
@ybungalobill_Are you saying content of a pointer is not physical address?
Pooria
@Pooria: Yes. I can't explain this in a few words. see: http://en.wikipedia.org/wiki/Virtual_address_space
ybungalobill
+6  A: 

There is always a physical address of 0 (but it may not necessarily map onto physical RAM), but on a typical platform any accesses will typically be performed in a virtual address space (as jweyrich points out below, you can use mmap and so on to directly map the physical address space), so any attempt to read/write to address 0 will raise an exception of some kind.

On simpler processors (think microcontrollers and so on), there may be no such protection, so if you attempt to write to address 0, there'll be nothing to catch you.

Note also that a null pointer doesn't necessarily have to point at address 0; the only guarantee is that it will compare equal to integer value 0.

Oli Charlesworth
`There is always a physical address of 0` - there's probably a weird microcontroller somewhere that hasn't got a physical address of 0 defined for some reason.
Skizz
@Oli Charlesworth: `but on a typical platform any accesses will be performed in a virtual address space` - that's not completely true. For instance, Linux allows you to `mmap()` the address 0 when `/proc/sys/vm/mmap_min_addr` is set to 0. That's how null-pointer-dereference bugs have been exploited :-)
jweyrich
@Skizz: Some microcontrollers do indeed map certain physical addresses to locations other than RAM, e.g. I/O registers, etc., so I'll update the answer accordingly.
Oli Charlesworth
@jweyrich: Answer updated accordingly...
Oli Charlesworth
Skizz: Yes - many CPU:s map SDRAM from address 0 and up. If no SDRAM is attached, address 0 is not defined.
kotlinski
@Oli Charlesworth_So, a pointer may even points to some cpu register, right?
Pooria
@Pooria: On e.g. a PIC, yes; all registers are memory-mapped.
Oli Charlesworth
After all I still think content of a pointer we're using is real physical address, am I wrong?
Pooria
@Pooria: I don't understand what you are asking!
Oli Charlesworth
@Oli Charlesworth_I mean address content of a pointer in our code doesn't necessarily has to be added to some base address to turn into physical address and depends on the platform right?
Pooria
@Pooria: Yes, pointers can be physical addresses on some platforms.
Oli Charlesworth
@Oli Charlesworth: actually, there's a misquote on my previous comment. It should've been `any attempt to read/write to address 0 will raise an exception of some kind`. Sorry if it caused a confusion. In fact, `mmap` maps a virtual address (even 0), so nevertheless, the NULL pointer would still point to a valid address.
jweyrich
@jweyrich: I'm not sure if I follow you. Are you saying that if you use `mmap` to map something onto virtual address 0, it will still be distinguishable from a null pointer?
Oli Charlesworth
@Oli Charlesworth: no. I'm saying you edited your answer to mention that `mmap` is able to map the specified physical address, which is not the case. I believe my misquote caused this confusion. I actually wanted to quote the other part (as mentioned above), which only rises the point that after that `mmap` call, dereferencing a NULL pointer would access a valid address.
jweyrich
@jweyrich: I assumed you were talking about using `mmap` to map `/dev/mem`. Regarding your actual point, so is it actually possible to `mmap` virtual address 0?
Oli Charlesworth
@Oli Charlesworth: I didn't think about /dev/mem, but that's correct. It gives you physical access. For the virtual address question, the answer is yes. It's possible calling `mmap` with the address 0, plus `MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE` flags, and desired read/write permissions.
jweyrich
+3  A: 

Yes, in many systems (especially embedded) there is a memory address 0, which is legal to read and write from.

On such systems, it may be optional to set up a trap that catches such read/writes.

kotlinski
+2  A: 

Yes, computers can have a physical address 0. For example, in the old DOS days, you'd regularly poke around there - that's where the interrupt table started - so if you wanted to know what would run on a keypress or timer interrupt then you could create a pointer to an array of pointers, and point that at 0. I reviewed the wording in the C++ Standard a couple years ago to see if this is necessarily undefined behaviour on a system where address 0 should be accessible (at a CPU/architecture level), and my recollection is that it wasn't explicit in saying this would cause undefined behaviour. Still, it basically reserves the right to load a non-0 value when you put 0 into a pointer, compare a pointer to 0 etc: 0 is a special sentinel value that it can do whatever it likes with, so if you cared about going "by the book" then you'd have to pussy-foot around.

Tony
+1  A: 

In kernel space yes NULL can be a valid address. In user space no. As for physical address, yes there always is address zero, but programs work with logical addresses.

Let_Me_Be
Please, see my comment about `mmap` on Oli Charlesworth's answer.
jweyrich
@jweyrich mmap is not part of C nor C++ standard it's part of the POSIX API.
Let_Me_Be
@Let_Me_Be: surely, but C and C++ standards don't define how a system should map its memory. Or do they?
jweyrich
@jweyrich No, but they define that you are working with logical memory space, not physical.
Let_Me_Be
@Let_Me_Be: Do they? And even if they do, they presumably don't dictate the mapping between logical and physical address spaces? So it could be direct.
Oli Charlesworth
@Oli Well, yes you can effectively have almost 1:1 mapping, but what is required is that NULL is not a valid address.
Let_Me_Be
@Let_Me_Be: Yes, `NULL` may well map to physical address 0, but the compiler shouldn't use that address for anything else.
Oli Charlesworth
+1  A: 

Note that even though the value 0 compares equal to a C/C++ NULL pointer, it is not guaranteed in the standard that a null pointer actually references address zero in the (virtual) address space of the process. (It usually does, but you know, there are bound to be some microcontrollers out there etc.) So *(reinterpret_cast<int *>(&my_pointer)) may not == 0.

On some versions of Unix (but not on Linux), every process has a read-only page containing only zero bytes mapped into its address space at address zero. On those machines, a null pointer always points to a zero value. There is software out there that makes use of this feature, and crashes when ported to Linux or Windows.

gpvos
So you tell that content of a pointer we're using is not necessarily physical address and it depends on platform?
Pooria
Well, firstly, it usually is not a physical, but a virtual address. Secondly, everything depends on the platform. I have never seen this myself, but I am just saying the same thing as Oli Charlesworth in another answer: "Note also that a null pointer doesn't necessarily have to point at address 0; the only guarantee is that it will compare equal to integer value 0".
gpvos
+1  A: 

Since this is tagged C++, it should be noted that the Standard guarantees that trying to access the "null pointer" via dereference evokes undefined behavior:

1.9 Program execution [intro.execution]

Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer). [Note: this International Standard imposes no requirements on the behavior of programs that contain undefined behavior. ]

...that the effect of a failed dynamic_cast is the null pointer, that deleteing the null pointer has no effect, and finally that the "null pointer constant" is == the integer expression 0:

4.10 Pointer conversions [conv.ptr]

  1. A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.
John Dibling