【问题标题】:Access Violation in Linked-List after copy constructor复制构造函数后链表中的访问冲突
【发布时间】:2015-06-10 04:17:52
【问题描述】:

我在 C++ 中创建了一个链接列表,但在将新项目插入列表时遇到了访问冲突。

如果从不调用复制构造函数并且在整个程序执行过程中使用原始列表,则该列表将完美运行。

在按值调用函数“outList”创建要在其范围内管理的列表副本后,插入方法中出现错误。

列表维护一个指向作为活动元素的 ListElement 的光标(指针)。该列表包含'gotoNext'和'gotoPrior'等方法。复制构造函数的目标是创建列表的深层副本并保持光标在副本中的位置。

在阅读代码之前,这里是堆栈跟踪,如您所见,程序在列表中仅添加一个元素后崩溃。

LinkedListExample.exe!LinkedList<char>::insert(const char & item, int position) Line 71 C++
LinkedListExample.exe!LinkedList<char>::LinkedList<char>(const LinkedList<char> & src) Line 35  C++
LinkedListExample.exe!main() Line 62    C++

这里是 Main()

void main()
{
    LinkedList<char> testList;      // Test list
    char insertChar;
    do{
        cin >> insertChar;
        outList(testList);
        testList.insert(insertChar, 0); //0 means insert after cursor, -1 insert before.
    }
    while(insertChar != 'q')
}

这里是清单

template <typename Type>
void outList(LinkedList<Type> list) 
{
    char tmp;
    if (list.empty())
       cout << "Empty list" << endl;
    else
    {
        list.gotoBeginning();
        do
        {
            tmp = list.retrieve();
            cout << tmp << " -> "; 
        }
        while (list.gotoNext());
        cout << endl;
    }
}

这里是 LinkedList 拷贝构造函数:

template <typename Type>
LinkedList<Type>::LinkedList(const LinkedList &src){
    if(src.head == NULL){
        head = NULL;
        cursor = NULL;
    }else{
        ListElement *iterator = src.head;
        ListElement *placeHolder = src.cursor;
        int numHops = 0;
        if(iterator->next == NULL){
            numHops = 1;
        }else{
            while(iterator != placeHolder){
                numHops++;
                placeHolder = placeHolder->next;
            }
        }
        iterator = src.head;
        while(iterator != NULL){
            insert(iterator->element, 0);
            if(iterator->next != NULL){
                iterator = iterator->next;
            }else{
                break;
            }
        }
        gotoBeginning();
        if(numHops != 0){
            for(int i = 0; i < numHops; i++){
                gotoNext();
            }
        }
    }
}

这里是链表插入:

template <typename Type>
void LinkedList<Type>::insert(const Type &item, int position){
    if(head == NULL){
        ListElement *newElement = new ListElement(item, NULL);
        newElement->next = NULL;
        head = newElement;
        cursor = head;
    }else if(position == 0){
        if(head->next == NULL){
            cursor = head;
        }
        //Create a new ListElement after the current.
        ListElement *newElement = new ListElement(item, NULL);
        //Preserve link (if there is one)
        if(cursor->next != NULL){
            newElement->next = cursor->next;
        }
        cursor->next = newElement;
        cursor = newElement;
    }else if(position == -1){
        //Add a new element before the current.
        ListElement *newElement = new ListElement(item, NULL);
        if(head->next == NULL || (cursor == head && cursor != NULL)){
            //Special case. There is only one node.  Must update head pointer.
            newElement->next = head;
            head = newElement;
            cursor = newElement;
        }else{
            //Node will be put between two other nodes.
            ListElement *iterator = head;
            while(iterator->next != cursor){
                iterator = iterator->next;
            }
            newElement->next = iterator->next;
            iterator->next = newElement;
            cursor = newElement;
        }
    }//end if line 24
}

供您参考,堆栈跟踪告诉我第 71 行是崩溃点。这是代码块“插入”中的那一行...

else if(position == 0){
            if(head->next == NULL){
                cursor = head;
            }
            //Create a new ListElement after the current.
            ListElement *newElement = new ListElement(item, NULL);
            //Preserve link (if there is one)
            if(cursor->next != NULL){ //LINE 71 LINE 71 LINE 71 LINE 71
                newElement->next = cursor->next;
            }

【问题讨论】:

  • placeHolder = placeHolder-&gt;next; 行似乎不对。你的意思是使用iterator = iterator-&gt;next;

标签: c++ list


【解决方案1】:

在你的复制构造函数中,如果src.head != null,那么headcursor 在你第一次调用insert 时不会被初始化。您可能打算将它们初始化为NULL

【讨论】:

    【解决方案2】:

    尝试使用此代码代替第 71 行

    else if(position==0){
    
    ListElement *newElement = new ListElement(item,NULL);
    
    if(head->next==NULL){
      cursor = head;
    }
    else{
      while (cursor->next!=NULL) { //placing the cursor on the last node inserted.
      cursor = cursor->next;
    }
    newElement->next = cursor->next;
    cursor->next = newElement;
    cursor = newElement;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 2016-02-08
      • 2012-03-06
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多