c++ - 当列表中有两个以上的项目时,链表的函数添加会崩溃?

标签 c++ templates pointers memory linked-list

下面列出的是我为使用链表概念的模板类添加的函数。出于某种原因,列表中有两个对象会导致程序在运行时崩溃,而只有一个项目不会导致任何问题。我已经看了一段时间的代码,但我仍然没有设法找出问题所在。我确保为新项目动态分配内存,这样我的指针就不会指向垃圾内存。下面列出了 MapItem 的结构和函数 add 来给你们一个想法。

template <class keyType, class valueType>
void Map<keyType, valueType>::add(const keyType &key, const valueType &value)
{
    struct MapItem<keyType, valueType> *newItem; //create pointer to new map item
    newItem = new MapItem<keyType, valueType>; //dynamically allocate a new item on the heap
    newItem->key = key; //assign the key
    newItem->value = value; //assign the value

    if(sizeList == 0) //if linked list is empty, make newItem the HEAD
    {
        sizeList++; //increment size
        head = newItem; //set the HEAD of the list to newItem
        tail = newItem; //set the TAIL of the list to newItem
        newItem->prev = head; //previous item is the head (itself)
        newItem->next = head; //next item is the head (itself)
    }
    else //if the linked list is not empty, add it in
    {
        struct MapItem<keyType, valueType> *temp = head; //store the first element in the linked list in temp variable

        if(sizeList == 1) //if there is only one element in the list, check if they equal eachother
        {
            if(head->key != key)
            {
                tail = newItem; //assign newItem as the TAIL                
                head->next = tail; //assign the next of HEAD to the new map item
                head->prev = tail; //assign the previous of HEAD as the newItem (tail)
                tail->prev = head; //assign head to PREV of newItem (tail)
                tail->next = head; //assign HEAD to NEXT of newItem (tail)
                sizeList++; //increment size of list
            }
        //  else
        //      cout<<"Same key already exists"<<endl;
        }
        else
        {
            bool sameKey = false; //boolean value to check if the same key already exists, and if it does it will stop the loop
            int i = 1; //which item we are looking at in the list

            while(i <= sizeList && !sameKey) //while not past the end of the list, keep checking if a similar key exists
            {
                if(temp->key == newItem->key)
                    sameKey = true;
                else
                {
                    temp = temp->next; //go to the next map item
                    i++;
                }
            }

            if(!sameKey) //if the same key has not been found
            {
                temp->next = newItem; //assign newItem to NEXT of last node (temp) in our list
                newItem->prev = temp; //assign temp to PREV of newItem
                newItem->next = head; //assign HEAD to NEXT of newItem
                head->prev = newItem; //assign newItem to PREV of head
                tail = newItem; //assign newItem as the TAIL
                sizeList++;
            }
            else
                delete newItem; //deallocate memory of newItem
        }
    }
}

这是 MapItem 的结构:

template <class keyType, class valueType>
struct MapItem
{
    keyType key;
    valueType value;
    MapItem<keyType, valueType> *prev, *next;
};

析构函数:

template <class keyType, class valueType>
Map<keyType, valueType>::~Map()
{
    struct MapItem<keyType, valueType> *temp; //create temp variable to hold which item we are looking at in the list
    temp = head; //start at the head

    for(int i = 1; i <=sizeList; i++)
    {
        delete temp; //delete memory to pointed by temp

        if(i != sizeList) //if we are not at the last node
            temp = temp->next;
    }
}

最佳答案

我想我明白了——替换这条线

temp->next = newItem; //assign newItem to NEXT of last node (temp) in our list

tail->next = newItem; //assign newItem to NEXT of last node (temp) in our list

因为当您循环遍历项以查找键时,您会回到 head - 因此在循环完成后“temp”指向“head”。但是你想在最后添加。

在此更改之前,我确实在销毁期间遇到了内存访问冲突(尽管我不明白为什么在删除析构函数代码后仍然出现一些错误)。

为清楚起见,析构函数代码:

~Map()
{
    struct MapItem<keyType, valueType> *temp; //create temp variable to hold which item we are looking at in the list
    temp = head; //start at the head

    for(int i = 1; i <=sizeList; i++)
    {
        MapItem<keyType, valueType> *next = temp->next;

        delete temp; //delete memory to pointed by temp

        if(i != sizeList) //if we are not at the last node
            temp = next;
    }
}

关于c++ - 当列表中有两个以上的项目时,链表的函数添加会崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26033077/

相关文章:

c++ - 工厂方法中的输出参数

templates - 如何提供预渲染的数据可绑定(bind)模板

c++ - 尝试验证日期时 undefined reference

C++,Send() 函数发送额外字节

c++ - 模板使用不当?

python - 在没有 Django 其余部分的情况下使用 Django 的模板引擎

c - 在C中通过引用传递多维数组

改变 const 指针的值

c - C 中的指针,来自下面的代码

C++ - 格式奇怪的十六进制输出