c++ 无法从节点列表中删除节点

5hcedyr0  于 2023-02-01  发布在  其他
关注(0)|答案(2)|浏览(135)

我在尝试执行delete_all()函数时遇到了一个小问题。知道为什么Visual Studio会向我抛出一个错误吗?
为RtlValidateHeap、指令__debugbreak()或类似内容指定的地址无效
一切都工作完美,直到我要执行这个函数。

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

mnemlml81#

我们在main()中声明了一个对象,并将自动存储持续时间作为列表的第一个节点:

node n1;

不能使用delete运算符销毁它。
使用列表实现的方法,可以按以下方式定义函数delete_all()

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

但是,如果最初在main()中声明了一个指向node的指针,那么效果会更好,在这种情况下,您需要更新函数。

busg9geu

busg9geu2#

您的delete_all()实现很好,但是您传递了一个指向node示例的指针,而该示例不是使用new创建的,因此delete 'ing该节点是 * 未定义的行为 所有 * 节点示例都应该动态创建,包括第一个节点。
因此,如果first最初是NULL,则add()函数应该更新为 not 盲目返回而不创建新的node示例。相反,您应该更新调用者的node*指针以指向创建的新node
此外,如果firstNULL,则writout()具有 * 未定义的行为 *,因为无论first是否是NULL,您都在 * 无条件地 * 访问first->next
话虽如此,尝试更像这样的东西代替:

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

或者:

...

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

相关问题