从链接列表中删除节点时不会出现错误

Deleting a node from a linked list without getting an error?

本文关键字:错误 节点 链接 列表 删除      更新时间:2023-10-16

简单地说,这个程序就是从字符串中创建一个字符链接列表。(从"HELLO"到head->h->e->l->l->o->NULL)每当我试图使用擦除功能删除磁头时,程序就会停止工作,给出"application.exe已停止工作…Windows正在检查解决方案…"。我想我的内存分配可能有问题,但我真的说不出来。非常感谢您的建议。

这适用于

void StringADT::append(string s)
{ 
for (int i = 0; i < s.length(); i++)
{
    Node* NodePtr;
    Node* newNode;
    newNode = new Node;
    newNode->data = s.at(i);
    newNode->next = NULL;
    if (!head)
    {
        head = newNode;
    } else
    {
        NodePtr = head;
        while (NodePtr->next)
        {
            NodePtr = NodePtr->next;
        }
        NodePtr->next = newNode;
    }
}
}
void StringADT::erase(int pos) //pos = position to erase
{
if (!head || pos < 0 || pos > length() - 1)
    return;
else {
    Node* NodePtr;  
    NodePtr = head;
    if (pos == 0)
    {   
        NodePtr = head->next;
        delete head; //PROBLEM COMES AFTER EXECUTION OF THIS LINE!!
    }
}

}

这是我的

class StringADT{
private:
    struct Node {
        char data;
        Node* next;
    };
    Node* head;

这是我的append函数,它可能是内存分配问题的根源。

void StringADT::append(string s) (appending string s to the linked list)
{ 
Node* NodePtr;
int slength = s.length();
Node *NodeArray;
NodeArray = new Node[slength];
if(!NodeArray)
    return;
for (unsigned i = 0; i < s.length(); i++)
{
    NodeArray[i].data = s.at(i);
    NodeArray[i].next = NULL;
}
if (!head)
{
    head = NodeArray;
    NodePtr = head;
    for(unsigned count = 1; count < slength; count ++)
    {
        NodePtr->next = (NodeArray + count);
        NodePtr = NodePtr->next;
        //cout << "number of count " << count << endl;
    }
} else {
    NodePtr = head;
    while (NodePtr->next)
    {
        NodePtr = NodePtr->next;
    }
    for(unsigned count = 0; count < slength; count ++)
    {
        NodePtr->next = (NodeArray + count);
        NodePtr = NodePtr->next;
        //cout << "number of count " << count << endl;
    }
}

}

擦除函数应该是这样的:

if (pos == 0)
{   
    NodePtr = head;
    head = head->next;
    delete NodePtr;
}

您按如下方式分配了Node对象:

NodeArray = new Node[slength];

在一个分配中有一个节点对象数组。稍后,当您对该数组中的特定元素执行操作时,您将调用

    delete head; //PROBLEM COMES AFTER EXECUTION OF THIS LINE!!

删除数组的特定元素

这在C++内存分配中是不允许的。

如果已经分配了一个数组,则只能删除整个数组,而不能删除特定的元素。此外,您还需要使用arraydelete[]运算符,如下所示:

delete[] someArray;

但这涉及到你的设计的一个根本问题。您正在实现一个链表,但您正在分配一个数组。现在,理论上,你可以像以前那样分配一个链表元素数组,但这样做没有意义。数组是为特定数量的元素分配的;当你需要任意数量的元素,却不知道这个数字是什么时,通常会使用链表。

链表通常一次分配和删除一个元素,而不是放在预定义的数组中。获取新数据时,分配一个新节点,然后将其添加到列表中。

(上面的代码味道是,如果你有一个数组,为什么你需要链接元素?你可以迭代到下一个元素,而不是跟随指针。数组和链表不是组合使用的;它们有不同的用途。对于链表,你应该去掉数组并分配单个节点,然后也可以单独删除它们根本没有那个数组。)

  1. 很明显,问题是您分配了对象数组,而不想删除其中一个。您必须独立分配Node。也就是说,这是您需要修复的append函数。

  2. append应该写成append(char),它只附加一个字符,而append(string const &)(字符串复制成本可能很高,所以总是通过引用,通常是常量!)应该只在循环中调用它。和append(char const *),所以您也可以附加字符串文字!

  3. 不要对没有随机访问权限的内容使用索引。为了让您不必考虑什么可以直接访问,只需学习更喜欢通过迭代器/指针进行迭代,而不是使用索引进行迭代!

我不举例子,因为对于任务,最好是你自己想出实际的代码,即使你必须反复要求澄清。