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

时间:2013-02-20 11:53:14

标签: c++ list linked-list

简单地说,这个程序是从字符串创建字符链表。 (从“HELLO”到头部 - > 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;

这是我的追加函数,由于内存分配,它可能是问题的根源。

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

}

3 个答案:

答案 0 :(得分:0)

擦除功能应该是这样的:

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

    delete NodePtr;
}

答案 1 :(得分:0)

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

NodeArray = new Node[slength];

您所拥有的是一个分配中的Node对象数组。之后,当您在该阵列中使用特定元素完成时,您正在调用

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

删除数组的特定元素

在C ++内存分配中不允许这样做。

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

delete[] someArray;

但这会导致您的设计出现根本性问题。您正在实施链接列表,但您正在分配数组。现在,从理论上讲,你可以像往常一样分配一系列链表元素,但这样做并没有意义。为特定数量的元素分配数组;当您需要任意数量的元素并且不知道该数字是什么时,通常会使用链接列表。

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

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

答案 2 :(得分:0)

  1. 问题显然是你分配了一些对象,而不想删除其中一个。您必须单独分配Node s。即这是您需要修复的append功能。

  2. 追加应该写成append(char),它只是附加一个字符而不是append(string const &)(字符串复制可能很昂贵,因此总是通过引用,通常是常量!)应该只是调用在循环中。还有append(char const *),所以你也可以附加字符串文字!

  3. 不要将索引用于没有随机访问权限的内容。因此,您不必考虑具有直接访问权限的内容,只需学习优先使用迭代器/指针迭代迭代索引!

  4. 我不会举例,因为对于作业而言,如果你自己想出实际的代码会更好,即使你不得不反复要求澄清。