3

This pointless question is about pointers, can someone point me in the right direction

Can the address of a variable ever be legitimately assigned a value of 0x000000, if so, does that mean for example:

#define NULL 0x00000000
int example;
int * pointerToObject = &example;

if(pointerToObject != NULL)

will return false?

Murasaki
  • 109
  • 1
  • 6
  • Possible duplicate: http://stackoverflow.com/questions/1296843/what-is-the-difference-between-null-0-and-0 ? – Morten Jensen Sep 19 '14 at 13:19
  • 2
    There is no guarantee that `NULL`, the "pointer pointing to nowhere valid", generates the same bit-pattern in the pointer variable as the correspondingly-sized integer `0` would do. Which makes this a bit question a bit imprecise. – unwind Sep 19 '14 at 13:20
  • @unwind in c++ there **is** warranty of 0 being the value of pointer to nowhere. Stroustrup discourages the use of NULL as a constant pointer value pointing to nowhere, as it is defined in a #include file and as that, there is no warranty of having the proper value. Stroustrup uses 0 as the value for a pointer pointing to nowhere in every part of his book. – Luis Colorado Sep 22 '14 at 07:03
  • @LuisColorado Yes, but I think the current recommendation is to use [`nullptr`](http://stackoverflow.com/questions/1282295/what-exactly-is-nullptr). And, my point is that even though it says e.g. `char *nothing = 0;`, that *still* doesn't mean that if you looked at the variable `nothing` in memory you would see `CHAR_BIT * sizeof nothing` zero bits. There is no requirement that the runtime representation is "all bits zero", regardless of what the null pointer looks like in the code. – unwind Sep 22 '14 at 07:18
  • I don't know exactly the current recommendation, but anything recommended must be backwards compatible, which fixes value to 0 either case. – Luis Colorado Sep 22 '14 at 08:46

4 Answers4

10

No, you cannot get a valid (=nonnull) pointer p for which p != NULL returns false.

Note, however, that this does not imply anything about "address 0" (whatever that means). C++ is intentionally very abstract when referring to addresses and pointers. There is a null pointer value, i.e. the value of a pointer which does not point anywhere. The way to create such a pointer is to assign a null pointer constant into a pointer variable. In C++03, a null pointer constant was the literal 0, optionally with a suffix (e.g. 0L). C++11 added another null pointer constant, the literal nullptr.

How the null pointer value is represented internally is beyond the scope of the C++ language. On some (most?) systems, the address value 0x00000000 is used for this, since nothing a user program can point to can legally reside at that address. However, there is nothing stopping a hardware platform from using the value 0xDEADBEEF to represent a null pointer. On such platform, this code:

int *p = 0;

would have to be compiled as assigning the value 0xDEADBEEF into the 4 bytes occupied by the variable p.

On such a platform, you could legally get a pointer to address 0x00000000, but it wouldn't compare equal to 0, NULL or nullptr.


A different way of looking at this is that the following declarations are not equivalent:

int *p = 0;
int *q = reinterpret_cast<int*>(0);

p is initialised with the null pointer value. q is initialised with the address 0 (depending on the mapping used in reinterpret_cast, of course).

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • what if you are on an small µC and the complete data memory is yours? the linker may place data objects to address 0 since its not occupied by other stuff and it is a valid address? – vlad_tepesch Sep 19 '14 at 13:36
  • @vlad_tepesch As I said, nothing forces the address value `0` to be used as the null pointer value. The compiler will simply have to use a bit pattern which cannot occur in a valid pointer, or reserve one if none such exists. – Angew is no longer proud of SO Sep 19 '14 at 13:40
  • @but hoq can the compiler distinguish between "assigning the address 0x00" from "set pointer to NULL" (if not `nullptr` is used)? – vlad_tepesch Sep 19 '14 at 13:43
  • @vlad_tepesch Simple. You cannot assign an integer into a pointer, and assigning the literal `0` is *explicitly defined* as assigning the null pointer value. If you want to assign the address `0x00000000`, you have to read the compiler's docs on doing that (it will probably involve `reinterpret_cast(0)`, but it's fully up to the compiler). – Angew is no longer proud of SO Sep 19 '14 at 13:45
  • Beautiful answer but do you know a deadbeef equivalent for x64? ;-) – Bathsheba Sep 19 '14 at 16:51
  • @Bathsheba You could try to `0xFEEDdeadBEEFaBED`; BTW, you're not the [first to ask this](http://stackoverflow.com/q/1258051/1782465). – Angew is no longer proud of SO Sep 19 '14 at 18:00
3

Yes, sure, you can have null pointers. And that check in your question will return false for null pointers. For example, malloc() can return a null pointer on failure and you'd better check for that.

0x000000 is interpreted as zero literal by the compiler and so can yield a null pointer. Same as code from here:

int* ptr = int();
Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
3

You first have to underestand how is allocated memory when you execute a given program.

There is three kinds of memory:

  1. Fixed Memory
  2. Stack memory
  3. Heap memory

Fixed Memory

  • Executable code
  • Global variables
  • Constant structures that don’t fit inside a machine instruction. (constant arrays, strings, floating points, long integers etc.)
  • Static variables.
  • Subroutine local variable in non-recursive languages (e.g. early FORTRAN).

Stack memory

  • Local variables for functions, whose size can be determined at call time.
  • Information saved at function call and restored at function return:
    • Values of callee arguments
  • Register values:
    • Return address (value of PC)
    • Frame pointer (value of FP)
      • Other registers
  • Static link (to be discussed)

Heap memory

  • Structures whose size varies dynamically (e.g. variable length arrays or strings).
  • Structures that are allocated dynamically (e.g. records in a linked list).
  • Structures created by a function call that must survive after the call returns.

Issues:

  • Allocation and free space management
  • Deallocation / garbage collection

How is the program loaded into memory?

When a program is loaded into memory, it is organized into three areas of memory, called segments: the text segment, stack segment, and heap segment. The text segment (sometimes also called the code segment) is where the compiled code of the program itself resides. This is the machine language representation of the program steps to be carried out, including all functions making up the program, both user defined and system.

The remaining two areas of system memory is where storage may be allocated by the compiler for data storage.

How is memory organized

enter image description here

Of course the zero you see in that image is relative to the offset.

Conlcusion

Even if a program is allocated into memory starting at address 0x00000000 there is no way that storage mechanism asign that address to a constant, static, or dinamic data that program uses. Since al those elements are stored in the data, heap or the stack sections and at the same time those are allocated after the .text section.

Discussion

I think that NULL pointers are set to 0x000000 by the reason that there is no way a variable(dinamic, local, static or global) be allocated at that address.

Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
  • this mostly only applies to PC and von-Neumann-Architectures but not to Harvard like architectures where you have a different address space for data. – vlad_tepesch Sep 19 '14 at 13:55
  • @vlad_tepesch In Harvad arquitectures, data address can be zero? – Raydel Miranda Sep 19 '14 at 13:57
  • why not? where are different memories. that addresses the manufacturer assigns to them is up to them. on AVR for example. the programm memory starts at 0x0. the data memory address space starts also at 0x0 but the lowest 0x1f adresses are mapped to registers that have special opcodes. i do not have an concrete example. maybe manufacturer explicitly design the chips in that way, that a data pointer can not end up being `0x0`. – vlad_tepesch Sep 19 '14 at 14:02
0

It it not possible for C++ to access the memory with address 0. C++ reserves that value (but not necessarily that physical address) for a null pointer.

So your statement if (pointerToObject != NULL) will never be false.

Pre C++11 you'd refer to that pointer using NULL which, typically, was a macro defined to 0 or (void*)0. In C++11, the keyword nullptr is used for that specific pointer value.

One useful property is that delete p will be benign if p == nullptr. free in C has the similar property.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483