【问题标题】:Trying to write my own linked list impementation in c++, code segfaults after hitting 3 elements in the list尝试用 C++ 编写我自己的链表实现,在列表中点击 3 个元素后出现代码段错误
【发布时间】:2018-12-29 02:49:05
【问题描述】:

我一直在尝试编写自己的链表实现,但是当我尝试访问第三个元素或之后的任何内容时,代码会出现段错误。添加元素不会出现段错误,但访问会。我在 get() 函数中找不到指针错误。

列表中的每个节点都存储(模板 t 的)数据和指向下一个节点的指针。我对所有东西都有两个功能——一个用于第一个元素,一个用于任何后续元素。后续元素的 get() 函数始终存在段错误。我在函数中有一些调试消息会吐出我无法解释的结果。例如,如果我对第二个元素(然后是第三个元素)运行 get() 请求,则代码不会出现段错误,但它确实返回了明显不正确的结果。我放置的调试消息表明,当第二个元素调用函数检查第三个元素时,会发生段错误,如果它发生的话。尝试使用和不使用 cout

一个可能的原因是指针存储——我让 get() 函数在循环遍历时输出每个元素(第一个元素除外)的指针,并将它们与 add() 函数输出的指针进行比较,并且元素 0 和 1 的指针匹配,但 2 及以上不匹配,我似乎无法弄清楚为什么会这样。

#include <iostream>
using namespace std;



template <class T> class myLinkedList{
T data;
myLinkedList<T> *next = NULL;

public:
    myLinkedList(T input){
        data = input;

    }
    void add(T input){
        if(next == NULL){
            myLinkedList<T> newItem(input);
            next = &newItem;
            cout << "adding to list, data is " << input << ", pointer is " << next << endl;
        }else{
            myLinkedList<T> nextEntry = *next;
            nextEntry.add(input);
        }
    }


    T getData(){
        return data;
    }
    //the start  of the get function, only used by the first entry in the list
    T get(int entry){
        int currentPosition = 0;
        if(entry == currentPosition){
            return getData();
        }else{
            //defrefrence the pointer anc check the next entry
            myLinkedList<T> nextEntry = *next;
           return nextEntry.get(entry, ++currentPosition);
        }
    }

private:
    //this vesion is the hidden, private vesion only used by nodes other than the first one
    //used to keep track of position in the list
    T get(int entry, int currentPosition){
        //cout << currentPosition << endl;
        if(entry == currentPosition){
            return data;
        }else{
            //derefrence the pointer and check the next entry
            cout << next << endl;
            myLinkedList<T> nextEntry = *next;
            currentPosition++;
           T output = nextEntry.get(entry, currentPosition);
           return output;
        }

    }


};
int main(){
myLinkedList<int> newList(3);
newList.add(4);
newList.add(5);
newList.add(7);
newList.add(9);
cout << newList.get(2) << endl;
cout << newList.get(3) << endl;
return 0;
}

结果显然是错误的——程序应该吐出两组指针,以及数字 5 和 7(列表元素)

【问题讨论】:

  • 在看这个之前,我要指出解决链表问题的两种最佳方法。 1) 画出列表的样子。这通常会建议如何编写代码,当您遇到错误时,请按照您的说明修改绘图。如果你发现自己画的东西很傻,那你只是发现了一个错误。
  • 2) 使用开发环境附带的任何调试器。调试器允许您按照自己的条件执行程序。您可以按您想要的任何粒度推进程序,并随时调查变量。如果您发现程序做了一些意想不到的事情,那么您只是发现了一个错误(或您的预期错误。您也需要修复它)。调试器是工作程序员必不可少的工具。它们可能是编译器这一端最好的生产力工具,所以你越早掌握它们,你就越早获得回报。
  • addmyLinkedList&lt;T&gt; newItem(input); 中的一个 bug(可能是 bug)声明了一个局部变量,这是一个自动分配,当它超出范围时将被销毁(程序到达封闭的 close支撑)。存储指向 this 的指针对您没有用处,因为指向的数据几乎立即消失,程序留下一个悬空指针。
  • 搞笑,我找不到您为每个新节点分配存储的位置?我错过了吗?
  • 链表是否应该拥有它链接的对象(并管理它们的生命周期)?

标签: c++ pointers


【解决方案1】:

您的主要问题之一在这里:

if(next == NULL){
    myLinkedList<T> newItem(input); // <<<<<<<<<<<<<
    next = &newItem;
    cout << "adding to list, data is " << input << ", pointer is " << next << endl;
}

您在if 范围内的堆栈上分配了一个项目。然后你让next指向这个项目。但是......项目的生命周期受此范围的限制。当您退出范围时,此项目不再存在。您需要通过“新”或其他方法动态分配它。

【讨论】:

  • 尝试使用 new (myLinkedList newItem = new myLinkedList(input);) 分配内存会导致一些令人费解的编译时错误 LinkedListTest.cpp:15:33: error: invalid conversion从 'myLinkedList*' 到 'int' [-fpermissive] 基本上,在 main 中调用 add 函数会导致一些指针问题 myLinkedList newItem = new myLinkedList(input);
  • myLinkedList&lt;T&gt; *newItem = new myLinkedList&lt;T&gt;(input); -- 这种情况下需要声明一个指针。
【解决方案2】:

我有了突破!遵循 Serge 的解决方案很有帮助,但还需要进行一项更改——而不是在我的 add 函数的 else 块中创建函数引用, 例如

 myLinkedList<T> nextEntry = *next;
 nextEntry.add(input)

我需要直接使用指针,如

next->add(input)

我不知道我的指针/对象语法

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 2020-06-17
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    相关资源
    最近更新 更多