More precisely, a pointer that points to NULL, or points to the address of 0x00000000. If you try to assign data to the value of a null pointer like this:

char *blah = NULL;
*blah = 'a';

You will usually get a GPF.

The null pointer is a special value for a pointer, of any type, indicating an (and "the") invalid location. There is only one null pointer. Thus, 2 null pointers will compare equal. You are not supposed to dereference the null pointer, and doing so results in undefined behaviour -- most environments will cause an exception or deliver a signal to the process if you do. However, e.g. on a VAX, not only may you dereference the null pointer, you even know you'll get a "0" if you do (for any primitive datatype).

In C and C++, you get a null pointer by implicitly typecasting 0 (note well: this is a literal 0) to a pointer. This is part of the language definition. But it does not follow that the internal representation of the null pointer in memory is all zeroes!

Rather, an implementation may choose any sentinel value (as long as it can never be a valid pointer, of course), and assign that value whenever a statement like char *p=0; is encountered. Some machines (AS/400, mainframes) may have completely different pointer formats than integer formats.

In particular, code such as char **p = calloc(100,sizeof(int)); is not guaranteed to make p point to an array of 100 NULL pointers! Rather, p points to a block of 100 pointers, but that block is zero-filled rather than NULL-filled. This type of bug is particularly insiduous, as almost all compilers will represent NULLs as zeroes, so you will not find it in QA unless you have such a platform.

To add to the confusion, using a pointer in an integer context (in C) or a boolean one (in C++) returns a true value unless the pointer is NULL. This is how you actually use it: no valid pointer to an object is equal to NULL (or 0, see below), so NULL is perfect for use as a sentinel value. It is usually used to denote conditions such as "no object" or "error". For instance, malloc() returns NULL if no memory could be allocated.

Proper C style is to use the macro NULL (#defined in stddef.h), whereas proper C++ style is simply to use 0.

Finally, Pascal uses nil for the pointer sentinel value; no conversion from an integer type is provided.

A good compiler won't let you compile code* like in ziplux's writeup - the general concept behind compiler warnings is to stop catastrophic logic errors like that. It's valid syntax, but...

* - MS Visual C++ gave an error, GCC gave a warning

Anyway.

Depending on the logic of your program, using null pointers can be perfectly feasible - one of the first things you'll learn in a data structures course is the structure behind a linked list, which almost always ends in a null pointer.

Especially by using the arrow operator and some basic logic controls, you can make nice use of null pointers, like so:


struct listNode
{
  int data;
  * listNode next;
};

void main()
{
  * listNode myNode; // Assume that myNode points to the front of a linked list

   while (myNode->next)
   {
     myNode = myNode->next;
     Your ultra-interesting code dealing with linked lists here
   } 
}

A rather juvenile example of what null pointers can be used for, but you'll see code like this a lot during your introductory programming courses. This code segment would theoretically work based on the idea that null pointers are inherently interpreted as false, thus making it very simple to execute full traversals.

Log in or register to write something here or to contact authors.