0

简单地说,这个程序是从一个字符串创建一个字符的链表。(比如从“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;

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

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

}

4

3 回答 3

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

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

  3. 不要对没有随机访问的事物使用索引。这样您就不必考虑直接访问的内容,只需学习更喜欢通过迭代器/指针进行迭代而不是使用索引进行迭代!

我不会给出示例,因为对于分配,最好自己提出实际代码,即使您必须反复要求澄清。

于 2013-02-20T12:37:26.080 回答
0

擦除函数应该是这样的:

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

    delete NodePtr;
}
于 2013-02-20T11:56:40.913 回答
0

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

NodeArray = new Node[slength];

在一个分配中拥有一Node 对象。稍后,当您处理完该数组中的特定元素时,您正在调用

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

删除数组的特定元素

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

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

delete[] someArray;

但这会导致您的设计出现根本问题。您正在实现一个链表,但您正在分配一个数组。现在,理论上你可以像你所做的那样继续分配一个链表元素数组,但这样做没有意义。为特定数量的元素分配一个数组;当您需要任意数量的元素并且不知道该数字是多少时,通常会使用链表。

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

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

于 2013-02-20T12:33:30.430 回答