More About Null Pointer Exception in C++

 We all might have encountered with the "infamous" Null Pointer Exception or Access Violation Exception during our development in C++.These seems to be pretty annoying especially when the code becomes complex and involves different modules.

Here we are going to have a closer look at Null Pointer case and try to understand or decode what causes this exception with an example.

Must Read : Memory Leak in C++

Understanding Null Pointer Exception Scenario

Below code presents an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Classic
{
public:
    string getName() const { return m_name; }
    void print()
    {
        cout << "Print called";
    }
private:
    string m_name;
};

int main()
{
    Classic* c = nullptr;
    c->print(); // did not throw exception
    string name = c->getName(); //Threw null pointer exception
    cin.get();
    return 0;
}

As shown in above code a Class Classic is defined with two member functions getName and print and there is a member variable named m_name.
Function getName tries to access the member variable, on the other hand print method does not access any memory.

Observation

In the main method I am creating a pointer of type Classic which is initialized to nullptr. using this pointer I am trying to invoke the member functions of the type Classic. Interesting thing is that the print method executes without any error even though it was called using a null pointer on the other hand getName throws the Null pointer/Access Violation exception as expected. Output is as shown below:

Output for the Null Exception code execution

So Why is this happening? 

Let us try to understand what might be happening during the compilation phase. During the compilation phase the class Classic gets converted to a structure with member variables and the member functions gets converted to public functions taking in the class instance as the first parameter as shown below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
struct Classic
{
    string m_name;
};

string Classic_getName(const Classic* self)
{
    return self->m_name;
}

void Classic_print(Classic* self)
{
    cout << "print called";
}


getName
takes in const version of the Classic object pointer because it's a const API. If we try to look at what we are doing in the print API It becomes evident that we are not trying to access the pointer passed or in other words we are not trying to access invalid memory, so the function print gets executed successfully

In the case of getName API we are trying to access the memory pointed by the self pointer and try to read the value stored in the memory identified by the member variable m_name, This causes the Null pointer exception or Access Violation exception.

Hope that this helped in understanding on what scenario the exception arises.



Comments

Popular posts from this blog

Creating RESTful Minimal WebAPI in .Net 6 in an Easy Manner! | FastEndpoints

Mastering Concurrency with Latches and Barriers in C++20: A Practical Guide for Students

Graph Visualization using MSAGL with Examples