Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在链表深度复制构造函数中,指针永远不会达到null_C++_Pointers_Linked List_Copy Constructor - Fatal编程技术网

C++ 在链表深度复制构造函数中,指针永远不会达到null

C++ 在链表深度复制构造函数中,指针永远不会达到null,c++,pointers,linked-list,copy-constructor,C++,Pointers,Linked List,Copy Constructor,我目前正在构建一个名为Sequence的链表类。有四个私有节点-headPtr、tailPtr、cursor(当前节点)和preducer(前一个节点) 我的复制构造函数在光标是列表中的最后一个项目时工作得很好,但是当光标处于中间时,由于函数的原因,函数从不退出while循环。p> 以下是复制构造函数: Sequence::Sequence(常量序列和copyMe){ 拷贝(copyMe); } 无效序列::复制(常量序列和copyMe){ numitems=0; if(copyMe.headP

我目前正在构建一个名为Sequence的链表类。有四个私有节点-headPtr、tailPtr、cursor(当前节点)和preducer(前一个节点)

我的复制构造函数在光标是列表中的最后一个项目时工作得很好,但是当光标处于中间时,由于函数的原因,函数从不退出while循环。p> 以下是复制构造函数:

Sequence::Sequence(常量序列和copyMe){
拷贝(copyMe);
}
无效序列::复制(常量序列和copyMe){
numitems=0;
if(copyMe.headPtr==nullptr){
光标=前驱体=头部PTR=尾部PTR=空PTR;
}
否则{
//为新序列分配一个新节点
node*newPtr=新节点;
newPtr->data=copyMe.headPtr->data;
numitems++;
//使用此节点启动新序列
headPtr=新PTR;
前体=nullptr;
游标=头PTR;
tailPtr=headPtr;
//创建节点以遍历原点序列
节点*originPtr=copyMe.headPtr->next;
while(originPtr!=nullptr){
//将节点添加到新列表中,使其成为当前节点,并分配数据(&S)
newPtr->next=新节点;
newPtr=newPtr->next;
newPtr->data=originPtr->data;
numitems++;
//正确的光标和光标位置
if(originPtr==copyMe.cursor){
此->光标=newPtr;
}
else if(originPtr==copyMe.preducer){
此->前体=新PTR;
}
originPtr=originPtr->next;
//如果被复制的东西是最后一件东西,请将其设置为tailptr
if(originPtr==nullptr){
tailPtr=newPtr->next;

cout复制构造函数的正确语法是:

Sequence::Sequence(const Sequence& copyMe) {...}
你写了:

void Sequence::copy(const Sequence& copyMe) {...}
这意味着您定义了一个成员函数而不是构造函数。因此永远不会调用您的构造函数。当您创建copy1、copy2和copy3时,将使用默认构造函数

更新

if (originPtr == nullptr) {

  tailPtr = newPtr->next; // newPtr->next is not initialized here
                          // consider tailPtr = newPtr instead
  cout << "tail assigned" << endl;

  newPtr->next = nullptr; // good
  originPtr = nullptr;    // originPtr is nullptr here because of if condition
}         
更新3

Sequence copy2(original);
original.remove_current(); // here you remove the last element
问题似乎出在
remove\u current()中
。构造函数中的循环不取决于光标位置。但它取决于原始序列的节点->下一个值。因此,创建副本时出错不会导致无限循环。无限循环的唯一原因是原始序列的格式不正确。我怀疑您忘了更新上一个no的
下一个
值在从序列中删除最后一个元素后执行de。在您发布remove_current()的代码之前,我无法证明我的话

更新4

void Sequence::remove_current() {
        if (is_item()) {

            node* temp;
            temp = cursor;

            if (cursor == headPtr && cursor == tailPtr) {
                cursor = nullptr;
                precursor = nullptr;
                headPtr = nullptr;
                tailPtr = nullptr;
            }
            else if (cursor == headPtr) {
                headPtr = cursor->next;
                cursor = headPtr;
                precursor = nullptr;
            }
            else {
                if (cursor == tailPtr) {
                    precursor->next = nullptr;
                    tailPtr = precursor;
                    cursor = precursor;
                    if (precursor == headPtr) {
                        precursor = nullptr;
                    }
                    else {
                        for(precursor = headPtr; precursor->next->next; precursor = precursor->next);
                    }
                }
                else {      
                    precursor->next = cursor->next;
                    cursor = cursor->next;

                }    
            }
            delete temp;
            numitems--;
        }
    }

1) 您是否尝试过使用调试器逐行检查代码,同时在每个执行步骤中观察每个变量的值,以查看它们是否符合您的期望值?2)请提供。减少TESTSIZE变量并在visual studio中逐步检查您的程序。这总能帮助我找到错误所在。我不确定问题是复制构造函数(对我来说似乎很好,正如您所说,我认为光标的位置不应该有任何区别)。但是自从上次调用复制构造函数以来,您对原始的
进行了相当多的修改,所以这可能就是问题所在。@n314159我省略了在尾部测试游标复制后测试语句的部分,因为它们都成功了。此外,所有这些函数都在早期成功的测试中使用看起来很干净,1)减小测试输入大小2)尝试独立运行测试3)在
remove_current
之后执行操作后检查originPtr.preducer和originPtr.cursor的行为实际的复制构造函数是
Sequence::Sequence(const Sequence©Me){copy(copyMe);}
,它调用此函数是所有修复循环问题的函数,但会导致分段错误。请参见输出:我已将其更改为
if
,而不是
else if
,但仅此一项并没有任何区别。以下是
删除当前():
和对
副本的修复:
:。没有分段错误,但仍在loop@NP2000我的怀疑成真了。请看更新4
else if (originPtr == copyMe.precursor) { // consider removing 'else' here
Sequence copy2(original);
original.remove_current(); // here you remove the last element
void Sequence::remove_current() {
        if (is_item()) {

            node* temp;
            temp = cursor;

            if (cursor == headPtr && cursor == tailPtr) {
                cursor = nullptr;
                precursor = nullptr;
                headPtr = nullptr;
                tailPtr = nullptr;
            }
            else if (cursor == headPtr) {
                headPtr = cursor->next;
                cursor = headPtr;
                precursor = nullptr;
            }
            else {
                if (cursor == tailPtr) {
                    precursor->next = nullptr;
                    tailPtr = precursor;
                    cursor = precursor;
                    if (precursor == headPtr) {
                        precursor = nullptr;
                    }
                    else {
                        for(precursor = headPtr; precursor->next->next; precursor = precursor->next);
                    }
                }
                else {      
                    precursor->next = cursor->next;
                    cursor = cursor->next;

                }    
            }
            delete temp;
            numitems--;
        }
    }