If you pay attention to your code, when you set a pointer to NULL, when you come back to it later you can tell that you definitely meant for this pointer to not be pointing at anything right now, and you can make sure not to accidentally use it.

That's pretty much it.

Some standard functions, if you feed them a NULL pointer, will spot that it's NULL and won't try to use it (which would cause a crash). Don't rely on that, though.

Edited 1 Year Ago by Moschops

As Moschops said, the NULL pointer is essentially a marker. Setting a pointer to NULL is a way of indicating the pointer is in an unusable state.

Now, as for it's uses, they mostly relate to handling dynamic memory. You generally want to initialize any pointer that you don't have an immediate value for to NULL, as an uninitialized pointer may or may not point to usable memory. If it is pointing to unusable memory, accessing it is almost certain to cause a memory violation exception such as a segmentation fault. and if it does point to usable memory, you won't know where it is pointing to, which mans that accessing that memory through it, or (even worse) changing the value of that memory could have unpredicatable results. To prevent this, you generally want to set a pointer to NULL, which is guaranteed to segfault if you access it; it is better for the program to fail outright in most cases than to continue in an unknown state. More importantly, because NULL is a known value, one which is always invalid, consistently setting unused pointers to NULL lets you check the state of the pointer. If you test the pointer's value against NULL before attempting to dereference it, you will know if the pointer is usable or not.

It is also important when working with dynamically allocated compound data structures, such as linked lists or trees. The usual practice is to use the NULL pointer to indicate the end of the list or the leaf nodes of trees. For example, if you have a list defined as

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

struct MY_LIST *head = NULL;

The fact that head is initialized to NULL lets you check to see if the list is empty or not; when you do create a list node and add it to the list, you would normally set next to NULL to show that it is the only element of the list so far. A simple set of list functions generally follows this pattern:

struct MY_LIST* makenode(int data)
{
    struct MY_LIST* node = malloc(sizeof(struct MY_LIST));

    node->data = data;
    node->next = NULL;
    return node;
}


/* add a node to the head of the list */
struct MY_LIST push(struct MY_LIST* list, int value)
{
    struct MY_LIST* list_body;

    if (list == NULL)
    {
        list = makenode(value);
    }
    else
    {
        list_body = list;
        list = makenode(value);
        list->next = list_body;
    }

    return list;
}

/* add a node to the end of the list */
struct MY_LIST add(struct MY_LIST* list, int value)
{
    struct MY_LIST  *new_node, *current_node, *previous_node;

    new_node = makenode(value)

    if (list == NULL)
    {
        list = new_node;
    }
    else
    {
        previous_node = list;
        current_node = list->next;

        //search for the end of the list
        while (current_node != NULL)
        {
            previous_node = current_node;
            current_node = current_node->next;
        }

        previous_node->next = new_node;
    }

    return list;
}

/* remove node from head of list */
struct MY_LIST* pop(struct MY_LIST)
{        
    if (head == NULL)
    {
        removed_node = NULL;
    }
    else
    {
        removed_node = head;
        head = head->next;
    }

    return removed_node;
}

You get the picture; the point is that NULL is used heavily in such data structures to indicate where the endpoints are.

@Schol-R-LEA - nice explanation! To expand, if one doesn't initialize pointers to NULL (or 0 - preferable for current systems), then you have introduced serious security flaws in your system.

This article has been dead for over six months. Start a new discussion instead.