Home > Mobile >  Can't delete node from node list
Can't delete node from node list

Time:01-31

I have a little problem which occurs after trying to execute function delete_all(). Any idea why Visual Studio is throwing me an error:

Invalid address specified to RtlValidateHeap, instruction __debugbreak() or something similar

Everything works perfect until I want to execute this function.

#include <iostream>

using namespace std;

struct node {
    string name = "n1";
    node* prev = NULL;
    node* next = NULL;
};

node* add(node* first, string name) {
    if (first == NULL) {
        return NULL;
    }

    node* nowy = new node;

    if (first->next == NULL) {
        nowy->prev = first;
        first->next = nowy;
    }
    else {
        while (first->next != NULL) {
            first = first->next;
        }
        nowy->prev = first;
        first->next = nowy;
    }

    nowy->name = name;

    return nowy;
}

void writeout(node* first) {
    if (first == NULL) cout << "first = NULL";

    while (first->next != NULL) {
        cout << first->name;
        cout << "\n";
        first = first->next;
    }

    if (first->next == NULL) {
        cout << first->name;
        cout << "\n";
    }
}

void delete_all(node* first) {
    node* temp;
    while (first != NULL) {
        temp = first->next;
        delete first;
        first = temp;
    }
}

int main()
{   
    node n1;

    add(&n1, "n2");
    add(&n1, "n3");

    writeout(&n1);

    delete_all(&n1);
}

CodePudding user response:

You declared an object in main() with automatic storage duration as the first node of the list:

node n1;

You may not destroy it using the delete operator.

Using your approach of the list implementation, you could define the function delete_all() the following way:

void delete_all(node* first) 
{
    if ( first != nullptr )
    {
        while ( first->next != nullptr ) 
        {
            node *temp = first->next;
            first->next = temp->next;
            delete temp;
        }
    }
}

But, it will be much better if initially in main(), you declared a pointer to a node. In this case, you will need to update the functions.

CodePudding user response:

Your implementation of delete_all() is fine, but you are passing it a pointer to a node instance that was not created with new, so delete'ing that node is undefined behavior. ALL of your node instances should be created dynamically, including the 1st node.

As such, your add() function should be updated to not blindly return without creating a new node instance if first is initially NULL. You should instead update the caller's node* pointer to point at the new node that was created.

Also, writout() has undefined behavior if first is NULL, because you are unconditionally accessing first->next whether first is NULL or not.

With that said, try something more like this instead:

#include <iostream>

using namespace std;

struct node {
    string name = "n1";
    node* prev = nullptr;
    node* next = nullptr;
};

node* add(node* &first, string name) {
    if (!first) {
        first = new node{name};
        return first;
    }
    else {
        node *prev = first;
        while (prev->next) {
            prev = prev->next;
        }
        prev->next = new node{name, prev};
        return prev->next;
    }
}

/* alternatively:

node* add(node* &first, string name) {
    node **nowy = &first, *prev = nullptr;
    while (*nowy) {
        prev = *nowy;
        nowy = &(prev->next);
    }
    *nowy = new node{name, prev};
    return *nowy;
}

*/

void writeout(node* first) {
    if (!first) {
        cout << "first = NULL";
    }
    else {
        do {
            cout << first->name;
            first = first->next;
            if (first) cout << '\n';
        }
        while (first);
    }
}

void delete_all(node* first) {
    node* temp;
    while (first) {
        temp = first->next;
        delete first;
        first = temp;
    }
}

int main()
{   
    node* n1 = nullptr;

    add(n1, "n2");
    add(n1, "n3");

    writeout(n1);

    delete_all(n1);
}

Alternatively:

...

node* add(node* first, string name) {
    if (!first) {
        return new node{name};
    }
    else {
        while (first->next) {
            first = first->next;
        }
        first->next = new node{name, first};
        return first->next;
    }
}

/* alternatively

node* add(node* first, string name) {
    // same as node** further above ...
}

*/

...

int main()
{   
    node* n1 = add(nullptr, "n2");
    add(n1, "n3");

    ...

    delete_all(n1);
}
  • Related