What is a Null Pointer in C/C++?

What is a Null Pointer in C

In this article, you will learn about NULL Pointers with the help of programming examples. If you don’t know what is pointer I recommend you first learn what a pointer is, you can check my other post “Pointer in C/C++“.

 

So let’s start the article with the introduction of NULL pointers.

 

What is a Null Pointer in C?

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; It expands to an implementation-defined null pointer constant.

C language gives the guarantee that the conversion of a null pointer to another pointer type yields a null pointer of that type. Also, any two null pointers will be equal.

Example of the NULL pointer in C,

int *ptr = NULL;  // ptr is a integer null pointer

 

wild pointer

Why do we need a NULL Pointer?

A null pointer prevents the surprising behavior of the program. If you forget to assign a valid address to the pointer at the time of declaration and later you will try to access the pointer, the program behavior may be undefined (UB). That means your program might not work as its implementation or it might be crashed.

Let’s see a program,

#include<stdio.h>

int main()
{
    //ptr pointing some unknown memory location
    int *ptr;

    //Assigning value
    *ptr = 12;

    printf("%d\n",*ptr);

    return 0;
}

Output:

Program Behavior Undefined.

 

Here using the NULL pointer you can avoid the undefined behavior of your C program. Now you are thinking how; don’t worry I am explaining the way.

In C/C++ programming a null pointer is guaranteed to compare unequal to a pointer to any object or function; that means (ptr1  == ptr2) is false. And any two null pointers will be equal which means ptr1 == ptr2 is true. So if you will initialize a pointer with NULL; it will help to avoid the undefined behavior. Consider the below code.

#include<stdio.h>

int main()
{
    /* no more wild pointer */
    int *ptr = NULL;
    
    /*
    if you forget to assign valid memory or,
    due to any reason your pointer not gets a memory
    */
    
    if(ptr != NULL)
    {
        //Assigning value
        *ptr = 26;
        printf("%d\n",*ptr);
    }
    
    return 0;
}

 

Look at the above code if in any circumstances your code failed to assign the memory to the ptr; in that scenario still, your code is safe because you have already put a condition prior to dereferencing the ptr.

So you must initialize the pointer with NULL (null pointer) and validate it before its use.

 

What is the usage of the NULL pointer in C?

There are many use cases of the null pointer in programming. I am mentioning a few of them that you must know.

1. If the pointer does not point to the address of a valid object or valid memory should be initialized to NULL. It prevents the pointer from becoming a wild pointer and ensures the programmer that the pointer is not pointing anywhere.

char *pcData = NULL; //Prevent becoming a wild pointer

 

2. Prior to dereferencing a pointer, you should validate it. It prevents undefined behavior. It also helps in error handling.

Example

The below code illustrates the handling of the pointers. It will not show undefined behavior if malloc will fail because we are validating null after calling the malloc().

#include<stdio.h>
#include<stdlib.h>

int main()
{
    int *piData = NULL;
    piData = malloc(sizeof(int)*10);
    if(NULL == piData)
    {
        //exit
    }
    else
    {
        //code
        free(piData); //free after the use
    }
    return 0;
}

 

3. Generally, daggling pointers arise when the referencing object is deleted or deallocated, without changing the value of the pointers. When you try to access the dangling pointer its shows UB. You can solve this problem by assigning NULL. See the below code,

#include<stdio.h>
#include<stdlib.h>

int main()
{
    char *ptr = NULL; //no longer wild pointer

    ptr = malloc(sizeof(char));
    if(ptr == NULL)
    {
        return -1;
    }

    /*ptr can be becomes a dangling pointer */
    free(ptr);

    //ptr is no longer dangling pointer
    ptr = NULL;

    return 0;
}

 

4. There are many library functions in C where pointer arguments are optional. So passing the null pointer to a function argument is useful when you don’t want to pass any valid memory or object address.

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);

Example:

#include <stdio.h>
#include <pthread.h>

void * test(void *input)
{
    printf("%s\n", (char *)input);
    pthread_exit(NULL);
}

int main()
{
    pthread_t tid;
    char name[] = "Amlendra";
    
    //passing NULL
    pthread_create(&tid, NULL, test,(void*)name);
    
    pthread_join(tid, NULL);
    
    return 0;
}

 

5. In a summary, you can understand that a null pointer can be used as an error value, a sentinel value, or terminate indirection in the recursive data structure.

 

 

What is the difference between an uninitialized pointer and a null pointer?

Both are different from each other but I have seen many people asking this question. So I am giving the answer to this silly question.

An uninitialized pointer is a pointer that points to an unknown memory location. The behavior of the uninitialized pointer is undefined. If you try to dereference the uninitialized pointer the behavior will be undefined.

example,

int *ptr; //uninitialized pointer or dangling pointer that points to any location in memory

 

The null pointer is an integer constant expression with the value 0 or such an expression cast to type void pointer. Dereferencing of null pointer would cause undefined behavior.

int* ptr = NULL; // normally points to zero or implementation-defined location.

 

 

Can we use the sizeof() operator on NULL in C?

Yes, you can use the sizeof operator on the null pointer. It returns the same size as it returns for other pointers. That means if the pointer size for a platform is 4 bytes, the sizeof() operator on NULL yields 4 bytes. And if the pointer size for a platform is 8 bytes, the sizeof() operator on NULL yields 8 bytes.

#include<stdio.h>

int main()
{
    int *ptr;

    printf("sizeof(NULL) = %u\n",sizeof(NULL));

    printf("sizeof(ptr) = %u\n",sizeof(ptr));

    return 0;
}

Output:

sizeof(NULL) = 4
sizeof(ptr) = 4

 

 

Summary and important points related to the null pointer:

 

1. An integer constant expression with the value 0 is also called a null pointer constant.

Example,

int *ptr = 0; // It is a legal statement in the context of a pointer and ptr is a null pointer constant.

2. If we compare the null pointer from the pointer that is pointing to any object or function, the comparison shall be unequal. The uninitialized pointer does not give any such type of guarantee.

Example:

In the below code always the body of the if statement will execute; the reason is that ptr1 is a null pointer and ptr2 is pointing to an object (data). And null-pointer cannot be generated by using the address-of operator on an object (e.g. &data).

#include<stdio.h>

int main()
{
    int data = 2;
    int *ptr1 = NULL;
    int *ptr2 = &data;

    if(ptr1 != ptr2)
    {
        printf("Always print\n");
    }
    else
    {
        printf("Never this body execute\n");
    }

    return 0;
}

 

 

3. If we convert the null pointer to another pointer of type T, the resulting pointer will be a null pointer of that type T.

char *ptr = NULL; //integer null pointer 

int *ptr = NULL; //char null pointer 

float *ptr = NULL; //float null pointer

 

4. In C, any two null pointers shall compare equal. That means expression ptr1 == ptr2 evaluates true.

#include<stdio.h>

int main()
{
    int *ptr1 = NULL;
    int *ptr2 = NULL;

    if(ptr1 == ptr2)
    {
        printf("Any two null pointers shall compare equal");
    }

    return 0;
}

 

5. The behavior of the unary * operator is undefined on null pointers (dereferencing the NULL pointers).

Example.

#include<stdio.h>

int main()
{
    int *ptr = NULL;

    //Undefine behavior
    printf("%d", *ptr);

    return 0;
}

 

6. Expression &*T is equivalent to T; even if Tis a null pointer.

 

You can check the below video to understand the NULL pointer and its usage in the programming language. Also, please subscribe to my channel.

 

Recommended Articles for you:

Leave a Reply

Your email address will not be published. Required fields are marked *