当前位置: 首页 > 知识库问答 >
问题:

复制构造函数后链接列表中的访问冲突

浦思源
2023-03-14

我在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++

以下是主要内容

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

以下是LinkedList插入:

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行是崩溃点。这是代码块“insert”中的那一行。。。

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

共有2个答案

酆恩
2023-03-14

试着用这个代码代替第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;
    }
}
葛季萌
2023-03-14

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

 类似资料:
  • 我正在尝试实现一个链表。 列表有私有变量*头,*尾,计数。 我理解数据结构中的逻辑,但不可否认,我是C语言的新手,所以我觉得我可能没有正确地使用构造函数。 *head和*tail是列表节点指针。然后,列表节点具有指向上一个和下一个(双链接列表)的指针。 以下是我尝试过的: 我的程序可以编译,但当它试图使用此构造函数创建新列表时崩溃。有什么建议吗?

  • 大家好,我正在学习Java中的构造函数链接,我有一些问题。。。 > 首先,有人能解释一下我什么时候需要使用这个吗?我真的想不出一个情况。 在这个例子中,在没有参数的构造函数中,我调用了另一个构造函数。我如何访问这个新的“詹姆斯·邦德”对象以备将来使用?

  • 问题内容: 有人可以说明一下可能有用的场景类型吗? 这是一种好的编程习惯吗? 问题答案: 这绝对是个好习惯,主要有两个原因: 避免代码重复 实施良好的封装

  • 我试图使用一个单独的节点类和LinkedList类创建一个基本的单链接列表。我几乎不知道自己在做什么,因为我刚刚开始学习C,所以非常感谢您的帮助。 代码的LinkedList部分是独立运行的,但我相信也有一些需要修改的地方。我的主要问题是,当试图添加到链接列表时,我得到(在LinkedList.h的第64行): 引发异常:读取访问冲突。这个- 我正在使用Microsoft Visual Studi

  • 主要内容:默认拷贝构造函数拷贝和复制是一个意思,对应的英文单词都是 。 对于计算机来说,拷贝是指用一份原有的、已经存在的数据创建出一份新的数据,最终的结果是多了一份相同的数据。例如,将 Word 文档拷贝到U盘去复印店打印,将 D 盘的图片拷贝到桌面以方便浏览,将重要的文件上传到百度网盘以防止丢失等,都是「创建一份新数据」的意思。 在 C++ 中,拷贝并没有脱离它本来的含义,只是将这个含义进行了“特化”,是指用已经存在的对

  • 所以我正在学习构造函数初始值设定项列表,我写了以下代码: 为此我使用了g编译器。它调用的是构造函数而不是复制构造函数。它应该调用复制构造函数,因为我正在创建一个对象来创建另一个对象?这里的问题是什么,标准对此怎么说?