了解为什么链表中存储的字符串无法正确打印

时间:2019-09-04 23:42:12

标签: c++ pointers linked-list g++

我正在做一个分配给我的特定成员函数,需要完成一个链表的工作。其中之一要求我复制一个节点,更改其名称,删除旧节点,然后将新节点重新插入列表中。我想出了这段代码

while(start != NULL)
{
    if(start->id == nID) 
    {
        start->name = newName;
        holdNode = start;
        removeNode(nID); //removes start from the linkedlist
        addNode(holdNode->name, holdNode->id, holdNode->cost); 

        found = true; 
        break;
    }
    else
        start = start->next; 

我在xcode中获得了正确的输出,但是当我使用g ++运行它时,名称字段为空或一系列随机字符。我猜想它与指向起始节点然后删除它有关,但是我不知道为什么它会在一个地方工作而在另一个地方工作。

Xcode输出

1, testing, $9.99

g ++

1, , $9.99

非常感谢您的帮助

1 个答案:

答案 0 :(得分:2)

您的代码未制作节点的任何副本。它仅更新找到的现有节点的name,然后将 pointer 保存到该节点,从列表中删除该节点使刚刚保存的指针无效,然后尝试使用该无效指针来获取插入新节点时要使用的值。这就是您的代码失败的地方。

尝试以下方法:

bool changeName(int nID, string newName)
{
    Product *node = head;

    while (node) //while there are items in the list
    {
        if (node->id == nID) //if ids match
        {
            double price = node->price;
            removeNode(nID); //remove node from the linkedlist
            addNode(newName, nID, price); //insert new node
            return true;
        }

        node = node->next; //move to next node
    }

    return false;
}

Live Demo

但是,这有点低效,因为removeNode()可能会再次进行相同的id搜索。链表能够迅速插入和删除节点,而无需多次遍历该列表。只需取消找到的节点与其周围节点的链接。至少,您可以像这样摆脱在removeNode()中对changeName()的呼叫:

bool changeName(int nID, string newName)
{
    Product *node = head, *prev = NULL;

    while (node) //while there are items in the list
    {
        if (node->id == nID) //if ids match
        {
            double price = node->price;

            //remove node from the linkedlist
            //removeNode(nID);
            if (prev) prev->next = node->next;
            if (node == head) head = node->next;
            delete node;

            //insert new node
            addNode(newName, nID, price);

            return true; 
        }

        prev = node;
        node = node->next; //move to next node
    }

    return false;
}

Live Demo

另一种选择是根本不破坏发现的节点,只需按原样重新定位它即可。将其与周围的节点断开链接,然后将其链接到所需新位置的节点,例如:

bool changeName(int nID, string newName)
{
    Product *node = head, *prev = NULL;

    while (node) //while there are items in the list
    {
        if (node->id == nID) //if ids match
        {
            //remove node from the linkedlist
            if (prev) prev->next = node->next;
            if (node == head) head = node->next;

            //insert node in new position
            Product **node2 = &head;
            while ((*node2) && ((*node2)->name < newName)) {
                node2 = &((*node2)->next);
            }

            node->name = newName;
            node->next = *node2;
            *node2 = node;

            return true; 
        }

        prev = node;
        node = node->next; //move to next node
    }

    return false;
}

Live Demo