Search code examples
c++inner-classesnull-pointer

Error C6011:Dereferencing NULL pointer 'NAME'. C++


As in the title my code gives the said warning and mashes up the memory references. I was tasked with using nested classes in C++. This code is mostly my code for linked lists from a previous C application but remade for C++. I ve searched on the internet about said NULL exception and I can t figure it out. I ll post the code and hope someone can give me some tips. In the various links and tips on the internet it says that the pointer I am pointing to is referencing to a NULLptr, and that it can t accces a NULL address. Tried to review it in various forms but it doesn t work.

Header

#ifndef LIST_H
#define LIST_H

#include <iostream>
#include <math.h>
using namespace std;

class List
{
private:
    class Node {
    public:
        int data;
        Node* next;
        Node() {
            this->data = NULL;
            this->next = NULL;
        }
    };
    Node* head;
public:
    List();
    void insertList(int data);
    void deleteFromList(int data);
    void deleteLowerThan(int lower);
    void calculateArithmetic();
    void showList();
};

#endif

Cpp file


List::List() {
    this->head = NULL;
}

void List::insertList(int n) {
    Node* new_node = new Node();


    new_node->data = n;

    new_node->next = head;

    head = new_node;

}

void List::deleteFromList(int n) {
    Node* temp = head;
    Node* prev = NULL;

    if (temp != NULL && temp->data == n) {
        head = temp->next;
        return;
    }

    while (temp->data != n && temp != NULL) {
        prev = temp;
        temp = temp->next;
    }

    if (temp == NULL) return;

    prev->next = temp->next;
}

void List::deleteLowerThan(int n) {
    Node* temp = head;
    while (temp != NULL) {
        if (temp->data < n) {
            deleteFromList(temp->data);
        }
        else {
            temp = temp->next;
        }
    }
}

void List::showList()
{
    Node* temp = head;
    while (temp != NULL)
    {
        cout << temp->data << " ";
        temp = temp->next;
    }
}

Driver



int main() {
    List lista;
    lista.insertList(2);
    lista.insertList(4);
    lista.insertList(6);
    lista.insertList(8);
    lista.insertList(3);
    lista.insertList(1);
    lista.insertList(-4);
    lista.showList();
    lista.deleteFromList(4);
    lista.showList();
    lista.deleteFromList(8);
    lista.showList();
    lista.deleteFromList(6);
    lista.showList();
    lista.deleteLowerThan(3);
    lista.showList();

    return 0;
}

Solution

  • As pointed out by Adrian and Andy, this line causes temp to be dereferenced before you check if it's NULL:

    while (temp->data != n && temp != NULL)
    

    so, just check that it's not NULL first, then dereference it.

    Other mentionable problems are the memory leaks. You should have exactly one delete for each new (unless you surrender the pointer to a smart pointer that will do delete for you).

    void List::deleteFromList(int n) {
        Node* temp = head;
        Node* prev = head;         // set this if you need to delete head
    
        if(temp != nullptr && temp->data == n) {
            head = prev->next;
            delete prev;           // you forgot this
            return;
        }
    
        while(temp != nullptr && temp->data != n) {
            prev = temp;
            temp = temp->next;
        }
    
        if(temp == nullptr) return;
    
        prev->next = temp->next;
        delete temp;              // you forgot this
    }
    

    You also need to implement a destructor in List to delete all the nodes in the List when it is destroyed.

    A trickier bug is in your deleteLowerThan() function. You iterate over the nodes in your list and call deleteFromList() which will delete the very node you are currently on. In the next iteration, you use the same node pointer in if (temp->data < n) { causing undefined behaviour. In my case, the program seemed to just hang forever.

    One possible fix:

    void List::deleteLowerThan(int n) {
        Node* temp = head;
        int tmpdata;
    
        while(temp != nullptr) {
            tmpdata = temp->data; // save the nodes data
            temp = temp->next;    // step before you delete
            if(tmpdata < n) {
                deleteFromList(tmpdata);
            }
        }
    }