Vlad Calotă
Vlad Calotă

Reputation: 33

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;
}

Upvotes: 1

Views: 11150

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

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);
        }
    }
}

Upvotes: 1

Adrian Mole
Adrian Mole

Reputation: 51825

The problem lies in your deleteFromList function, with this code:

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

Here, you are trying to check the value of temp->data before you have verified whether or not temp is NULL. Thus, you will, at some point (when you're at the end of the list, and temp is NULL be dereferencing a null pointer - which ain't good!

Instead, just invert the order of the comparisons:

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

This way, as soon as temp is NULL, the comparison's result will be fully known (see short circuiting), temp->data will not be evaluated, and the loop will stop running.

Upvotes: 2

Related Questions