leetcode链表题报错 runtime error: member access within null pointer of type ‘ListNode‘

这篇具有很好参考价值的文章主要介绍了leetcode链表题报错 runtime error: member access within null pointer of type ‘ListNode‘。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天在做leetcode203:移除链表元素时,反复遇到了报错:runtime error: member access within null pointer of type ‘ListNode’ (solution.cpp),报错提示的意思是试图访问’ListNode空指针类型的成员,就浅浅记录一下修复bug的过程吧。。。。

刚开始的代码是这样的,逻辑是先建立一个头结点放到链表头部,这样就可以统一链表结点删除的操作了,然后创建ListNode类型指针cur,初始化其指向头结点的下一个结点,利用while循环遍历链表,当cur指针指向Null时停止遍历。然后就报错了…

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyNode=new ListNode(0);
        dummyNode->next=head;
        ListNode* cur=dummyNode->next;
        ListNode* tmp=nullptr;
        while(cur!=nullptr){
            if(cur->val==val){
                tmp=cur->next;
                cur->next=cur->next->next;
                delete tmp;
                cur=cur->next;
            }else   cur=cur->next;
        }
        head=dummyNode->next;
        delete dummyNode;
        return head;
    }
};

报错的代码行是:cur->next=cur->next->next;,报错提示的意思是试图访问’ListNode空指针类型的成员,然后才发现原因出在:当移除的元素位于链表最后一个时,此时cur指向最后一个结点,cur->next为空,而访问cur->nex->next就是访问空指针的成员变量了

那么怎么解决这个问题呢?我最开始想到的办法是是增加判断语句,当cur指向的是最后一个结点时,就不执行
cur->next=cur->next->next;操作,而是将前一个结点的next指针置为空,但是因为cur指向的是当前结点,所以没有办法操作上一个结点,这个办法好像行不通。

于是我参考了代码随想录中的参考答案如下:

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
        dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
        ListNode* cur = dummyHead;
        while (cur->next != NULL) {
            if(cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
                cur = cur->next;
            }
        }
        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

可以发现这个代码与我的代码不同有两点:第一是cur指针初始化时指向的是头结点,而我的代码cur指向是指向头结点的下一个结点,即原始链表的第一个结点,第二是while循环中的条件为cur->next != NULL,即当cur结点的下一个结点不为空时继续循环,而我的代码是cur!=nullptr,即当前结点不为空时继续循环。

区别感觉很小,但是代码随想录中的这份代码并不会报错,原因就在这份代码的循环条件是cur->next != NULL,这样保证了cur->next不为空,因此就不会出现访问空指针的成员变量的情况;而且判断某结点的值时利用的是cur->next ->val进行判断,而不是让cur指针直接指向该结点,即利用cur->val判断,=这样做的好处是判断某一个结点的值时同时也能保留对其上一个结点进行修改的权利,这样当需要删除的元素在链表中最后一个时,可以很方便的将其前一个结点的next指针置为nullptr

于是我参考代码随想录把原始代码改成了下面的代码,但是一时脑瘫的在if(cur->next->val==val)的作用域最后多加了一句cur=cur->next;,以为此时指针也要后移一位,结果又遇到了同样的报错,而且报错转移到了if(cur->next->val==val)这一行,最后才反应过来,如果待删除元素位于链表最后,当执行完cur->next=cur->next->next时,cur->next为空,如果这时执行cur=cur->next;,则cur为空,等到下一次循环判断时,又会访问空指针成员变量,因此这一句不能加,同一个坑踩两次了属于是…而且在需要删除的结点情况下,cur指针不用后移,因为下一次循环cur->next访问的就是被删除节点的下一个结点了,这个逻辑当时也没理清。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyNode=new ListNode(0);
        dummyNode->next=head;
        ListNode* cur=dummyNode;
        ListNode* tmp=nullptr;
        while(cur->next!=nullptr){
            if(cur->next->val==val){
                tmp=cur->next;
                cur->next=cur->next->next;
                delete tmp;
                cur=cur->next;
            }else   cur=cur->next;
        }
        head=dummyNode->next;
        delete dummyNode;
        return head;
    }
};

最后总结来说:
1.利用让cur指针的移动范围为:[头结点,倒数第二个结点],比起范围为[第二个结点,最后一个结点]更加合理,可以有效处理待删除元素在链表尾部的问题,也能够避免bug的发生
2.使用链表时要严格检查有没有访问空指针的成员,特别要考虑待删除元素在链表边界的特殊情况

ps:如果细心的话可以发现代码随想录中判断空指针用的是Null,而我的代码里用的是nullptr,当时觉得有些疑惑,这里再简单总结一下在C++中Null和nullptr的区别:用Null表示空指针是C语言中遗留下来的传统,但在C++中可能会引起问题,因此在C++11中引入了nullptr表示空指针,如果要在C++中表示空指针,那么使用nullptr而不是Null.。文章来源地址https://www.toymoban.com/news/detail-675483.html

到了这里,关于leetcode链表题报错 runtime error: member access within null pointer of type ‘ListNode‘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QWidget 报错 error: no member named ‘XXXX‘ in ‘ui::Widget‘

    主要原因是我们在修改完ui界面时没有重新构建项目或者就是因为构建的项目与原项目不在同一个文件夹下面 1.点击项目-2.取消勾选shadow build.通过这两步,我们重建的项目的中间过程文件以及可执行文件就会生成在项目的目录下。 2.但这时可执行文件与中间过程文件都在deb

    2024年02月08日
    浏览(42)
  • 【算法】链表题的常用技巧及算法题(C++)

    下面的技巧通过一些后面的例题可以较好的理解熟练。 常用技巧 画图 链表题通过画图可以较为直观分析链表,方便分析如何进行对链表的操作等 引入虚拟“头”节点 虚拟节点适合处理一些边界情况 同时放便我们进行对链表的操作 多定义变量 多定义变量增强可读性,也方

    2024年02月03日
    浏览(43)
  • Unity 报错error CS0656: Missing compiler required member ‘Microsoft.CSharp.RuntimeBinder.CSharpArgumen

    error CS0656: Missing compiler required member ‘Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create’ unity报错及解决方案 今天用了一个开源的项目脚本,放到unity后报错了,查了资料说是缺Microsoft.CSharp包,添加了引用仍然无效,具体原因是因为脚本中用了dynamic类型。尝试了一些解决办法,最

    2024年01月18日
    浏览(37)
  • vue报错Uncaught runtime errors: × ERROR ResizeObserver loop limit exceeded at handleError (webpack

    Uncaught runtime errors: × ERROR ResizeObserver loop limit exceeded at handleError (webpack-internal:///./node_modules/webpack-dev-server/client/overlay.js:252:58) at eval (webpack-internal:///./node_modules/webpack-dev-serve 问题原因: 使用了el-table组件+弹性布局 弹性布局 单独使用都不会报错,但是两个结合在一起就产生了

    2024年02月11日
    浏览(48)
  • maven报错error while loading <root>, Error accessing

    [ERROR] error while loading root, Error accessing D:installjavaapache-maven-3.6.3respositoryorgapacheflinkflink-clients_2.111.13-tq-0.1.7flink-clients_2.11-1.13-tq-0.1.7.jar   Failed to execute goal net.alchim31.maven:scala-maven-plugin:3.4.6:compile (scala-compile-first) on project common-flink: wrap: scala.reflect.internal.MissingRequirementErro

    2024年02月12日
    浏览(47)
  • Kubeadm初始化报错:[ERROR CRI]: container runtime is not running:

    输入后再次执行kubeadm init,正常运行

    2024年02月12日
    浏览(48)
  • LeetCode:Line 1037: Char 34: runtime error: addition of unsigned offset to 0x502000000090 overflowed

    错误信息 在重刷47.全排列II时,写了如下代码: 出现如下错误信息: 错误定位 通过注释代码的方法,定位到错误的位置在 dfs 函数里的 if 判断: 错误原因 当 i 为 0 元素时,会执行 nums[i] == nums[i - 1] , i - 1 为负数,作为数组索引是不合法的,因此会报如上错误。换言之,

    2024年03月15日
    浏览(48)
  • nvm 安装 Node 报错:panic: runtime error: index out of range [3] with length 3

    最近在搞 TypeScript ,然后想着品尝一下 pnpm ,但是 pnmp 8.x 最低需要 Node 16.x ,但是电脑上暂时还没有该版本,通过 nvm list available 命令查看可用的 Node 版本: 既然有最高版本,那肯定直接上最高版本: 然后就报错了,错误信息如下: 出问题果断 Github 上去搜( 体会到了开源

    2024年02月16日
    浏览(49)
  • k8s初始化报错:[ERROR CRI]: container runtime is not running(已解决)

    如有错误,敬请谅解! 此文章仅为本人学习笔记,仅供参考,如有冒犯,请联系作者删除!!          在网上找了好几天解决方案,大部分都是下述方案:         但是当我们尝试之后仍无法解决问题。 如有错误,请联系作者删除 并恳请同行朋友予以斧正,万分感谢!

    2024年02月07日
    浏览(52)
  • docker 启动容器 报错 Error response from daemon: failed to create shim task: OCI runtime create failed

    Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: unable to apply apparmor profile: apparmor failed to apply profile: write /proc/self/attr/apparmor/exec: no such file or directory: unknown 解决方案

    2024年02月12日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包