Go invalid memory address or nil pointer dereference错误 空指针问题

Go 指针声明后赋值,出现 panic: runtime error: invalid memory address or nil pointer dereference,这种是内存地址错误。

首先我们要了解指针,指针地址
在 Go 中 * 代表取指针地址中存的值,& 代表取一个值的地址
对于指针,我们一定要明白指针储存的是一个值的地址,但本身这个指针也需要地址来储存

错误示例

package main

import "fmt"

func main() {
	var i *int

	fmt.Println(&i, i)

	*i = 1
	fmt.Println(&i, i, *i)
}

错误提示

0xc00009a008 <nil>

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1092f9c]

初始化指针,指针变量的地址为0xc00009a008, 指针值为nil
此时,i为nil,系统没有给*i分配地址,相当于给一个nil地址赋值,肯定会出错

解决办法是,预先分配一个内存地址给到指针变量

new初始化内存地址

package main

import "fmt"

func main() {
	var i *int

	fmt.Println(&i, i) // 0xc000094010 <nil>

	i = new(int)
	fmt.Println(&i, i, *i) //0xc000094010 0xc0000a2010 0
}
  • i 为指针变量,它的内存地址为0xc000094010
  • i的值为0xc0000a2010
  • 内存地址0xc0000a2010值为0
举个例子:

当status 请求参数超出范围时报错 runtime error: invalid memory address or nil pointer dereference

func UpdateRiskEventStatus(ctx *gin.Context, req *message.UpdateRiskEventStatusReq) (*message.UpdateRiskEventStatusResp, error) {
var (
err        error
now        = time.Now()
DealRecord = &models.DealRecord{}
result     = &message.UpdateRiskEventStatusResp{}
)

//1.修改事件状态
if req.Status < 0 || req.Status > 4 {
	log.Info("处置状态超出范围【0-4】")
	//result.ReplyErrCode(message.ParamsParseErrCode, err.Error())
	return result, err
}
err = models.UpdateRiskEventStatus(req.EventID, map[string]interface{}{
	"deal_status": req.Status,
})

if err != nil {
	result.ReplyErrCode(message.DBErrCode, err.Error())
	log.Errorf("UpdateRiskEventStatus.err: %v", err.Error())
	return result, err
}

2.增加人员操作记录
DealRecord.CreatedAt = now.Unix()
DealRecord.EventID = req.EventID
DealRecord.Status = req.Status
DealRecord.Remark = req.Remark
DealRecord.OperateUser = req.OperateUser
err = models.CreateDealRecord(DealRecord)
if err != nil {
	result.ReplyErrCode(message.DBErrCode, err.Error())
	log.Errorf("CreateDealRecord.err %v", err.Error())
	return result, err
}

return result, err
}    

在你的代码中,当 req.Status 超出预期范围时,你返回 resulterr,但在此之后,你仍然继续执行代码,而没有检查 result 是否为空。这可能导致在处理之后 result 是空指针,导致 "nil pointer dereference" 错误。

针对请求参数超出范围时,你已经返回了 resulterr,应该在这一点上结束函数的执行,而不是继续执行余下的代码。

建议在参数超出范围时直接返回,避免继续执行后续代码,可以像下面这样修改你的代码:

 err = errors.New("Status out of range [0-4]") // 注意添加测行,即可
func UpdateRiskEventStatus(ctx *gin.Context, req *message.UpdateRiskEventStatusReq) (*message.UpdateRiskEventStatusResp, error) {
    var (
        err        error
        now        = time.Now()
        DealRecord = &models.DealRecord{}
        result     = &message.UpdateRiskEventStatusResp{}
    )

    // 1.修改事件状态
    if req.Status < 0 || req.Status > 4 {
        log.Info("处置状态超出范围【0-4】")
        result.ReplyErrCode(message.ParamsParseErrCode, "Status out of range [0-4]")
        err = errors.New("Status out of range [0-4]") // 注意添加测行,即可
        return result, err
    }

    err = models.UpdateRiskEventStatus(req.EventID, map[string]interface{}{
        "deal_status": req.Status,
    })

    if err != nil {
        result.ReplyErrCode(message.DBErrCode, err.Error())
        log.Errorf("UpdateRiskEventStatus.err: %v", err.Error())
        return result, err
    }

    // 2.增加人员操作记录
    DealRecord.CreatedAt = now.Unix()
    DealRecord.EventID = req.EventID
    DealRecord.Status = req.Status
    DealRecord.Remark = req.Remark
    DealRecord.OperateUser = req.OperateUser
    err = models.CreateDealRecord(DealRecord)
    if err != nil {
        result.ReplyErrCode(message.DBErrCode, err.Error())
        log.Errorf("CreateDealRecord.err: %v", err.Error())
        return result, err
    }

    return result, err
}

这样修改后,当 req.Status 超出范围时,函数将立即返回,避免继续执行可能导致空指针错误的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/118563.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM 各个参数详解

在一些规模稍大的应用中&#xff0c;Java虚拟机&#xff08;JVM&#xff09;的内存设置尤为重要&#xff0c;想在项目中取得好的效率&#xff0c;GC&#xff08;垃圾回收&#xff09;的设置是第一步。 PermGen space&#xff1a;全称是Permanent Generation space.就是说是永久…

PDF文件解析

一、PDF文件介绍 PDF是英文Portable Document Format缩写&#xff0c;就是可移植的意思&#xff0c;它是以PostScript语言图象模型为基础&#xff0c;无论在哪种打印机上都可保证精确的颜色和准确的打印效果&#xff0c;PostScript咱也不懂&#xff0c;估计和SVG的原理差不多吧…

k8s提交spark应用消费kafka数据写入elasticsearch7

一、k8s集群环境 k8s 1.23版本&#xff0c;三个节点&#xff0c;容器运行时使用docker。 spark版本时3.3.3 k8s部署单节点的zookeeper、kafka、elasticsearch7 二、spark源码 https://download.csdn.net/download/TT1024167802/88509398 命令行提交方式 /opt/module/spark…

14:00面试,14:06就出来了,问的问题有点变态。。。。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到5月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

pytorch3D Windows下安装经验总结

一、说明及准备工作 最近在安装pytorch3D的时候遇到了很多问题&#xff0c;查了很多博客&#xff0c;但发现讲的都不太全&#xff0c;所以特将自己的及收集到的安装过程经验总结如下。我是在Anaconda中虚拟环境下安装的。 1.1准备工作 官方安装教程如下&#xff1a;https://…

Docker Tomcat 搭建文件服务器

本文基于openwrt上进行。 步骤 1: 安装 Docker 如果尚未安装Docker&#xff0c;首先需要安装Docker。根据你的操作系统&#xff0c;参考Docker官方文档来完成安装, 这里不做详细介绍。 步骤 2: 拉去docker Tomcat镜像 进入openwrt管理界面&#xff0c;docker选项中 拉取最新…

Java 设计模式——外观模式

目录 1.概述2.结构3.实现3.1.子系统类3.2.外观类3.3.测试 4.优缺点5.使用场景6.源码解析 1.概述 &#xff08;1&#xff09;有些人可能炒过股票&#xff0c;但其实大部分人都不太懂&#xff0c;这种没有足够了解证券知识的情况下做股票是很容易亏钱的&#xff0c;刚开始炒股肯…

Zeus IoT : 基于 SpringBoot 的分布式开源物联网大数据平台

Zeus IoT 是一个集设备数据采集、存储、分析、观测为一体的开源物联网平台&#xff0c;全球首创基于 Zabbix 的物联网分布式数据采集架构&#xff0c;具备超百万级物联网设备的并发监控能力&#xff0c;真正具备工业级性能与稳定性的开源物联网大数据中台。 Zeus IoT 致力于让设…

Zinx框架-游戏服务器开发002:框架学习-按照三层结构模式重构测试代码+Tcp数据适配+时间轮定时器

文章目录 1 Zinx框架总览2 三层模式的分析3 三层重构原有的功能 - 头文件3.1 通道层Stdin和Stdout类3.1.2 StdInChannel3.1.2 StdOutChannel 3.2 协议层CmdCheck和CmdMsg类3.2.1 CmdCheck单例模式3.2.1.1 单例模式3.2.1.2 * 命令识别类向业务层不同类别做分发 3.2.2 CmdMsg自定…

Node.js |(五)包管理工具 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;概念介绍&#x1f4da;npm&#x1f407;安装npm&#x1f407;基本使用&#x1f407;生产依赖与开发依赖&#x1f407;npm全局安装&#x1f407;npm安装指定包和删除…

4、Python基本数据类型:数字、字符串、列表、元组、集合、字典

文章目录 1、Python基本数据类型简介2、数字3、字符串4、列表5、元组6、集合7、字典1、Python基本数据类型简介 Python是一种非常强大且易于学习的编程语言,它具有简洁的语法和丰富的数据类型。了解和掌握Python的基本数据类型是学习和使用Python的基础。本文将详细介绍Pytho…

Disk Drill v5.3.1313(数据恢复备份)

Disk Drill是一款功能强大的数据恢复软件&#xff0c;它可以帮助用户恢复已删除、丢失、格式化或损坏的文件&#xff0c;并支持多种存储设备&#xff0c;包括计算机硬盘驱动器、外部硬盘、USB闪存驱动器、内存卡和其他存储介质。它和很多的文件系统都兼容&#xff0c;比如&…

nodejs express uniapp 图书借阅管理系统源码

开发环境及工具&#xff1a; nodejs&#xff0c;mysql5.7&#xff0c;HBuilder X&#xff0c;vscode&#xff08;webstorm&#xff09; 技术说明&#xff1a; nodejs express vue elementui uniapp 功能介绍&#xff1a; 用户端&#xff1a; 登录注册 首页显示轮播图&am…

排序算法的分析及实现

目录​​​​​​​ 1. 排序 1.1. 排序的概念 1.2. 排序的稳定性 1.3. 内部排序和外部排序 2. 直接插入排序 2.1. 直接插入排序 2.2. 直接插入排序的两种情况 1. 情况一 2. 情况二 2.3. 直接插入排序的单趟排序 2.4. 直接插入排序的完整实现 2.5. 直接插入排序的时…

【江协科技-用0.96寸OLED播放知名艺人打篮球视频】

Python进行视频图像处理&#xff0c;通过串口发送给stm32&#xff0c;stm32接收数据&#xff0c;刷新OLED进行显示。 步骤&#xff1a; 1.按照接线图连接好硬件 2.把Keil工程的代码下载到STM32中 3.运行Python代码&#xff0c;通过串口把处理后的数据发送给STM32进行显示 …

【图像分类】【深度学习】【Pytorch版本】AlexNet模型算法详解

【图像分类】【深度学习】【Pytorch版本】AlexNet模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】AlexNet模型算法详解前言AlexNet讲解卷积层的作用卷积过程特征图的大小计算公式Dropout的作用AlexNet模型结构 AlexNet Pytorch代码完整代码总结 前言 AlexNet是…

论文阅读——What Can Human Sketches Do for Object Detection?(cvpr2023)

论文&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Chowdhury_What_Can_Human_Sketches_Do_for_Object_Detection_CVPR_2023_paper.pdf 代码&#xff1a;What Can Human Sketches Do for Object Detection? (pinakinathc.me) 一、 Baseline SBIR Fram…

Cesium:WFS请求两种方式

以本地发布的上海市浦东区行政区划WMS地图服务为例,讲述Cesium中WFS请求的两种方式及其优缺点。 服务加载地址及其参数如下, 服务加载地址:http://localhost:8089/geoserver/pudong/wms 加载参数:layerName:pudong:distractservice: "WMS",request: "GetMa…

8-2、T型加减速计算简化【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍简化T型加减速计算过程&#xff0c;使其适用于单片机数据处理。简化内容包括浮点数转整型数计算、加减速对称处理、预处理计算 一、浮点数转整型数计算 1.1简化∆t_1计算 根据上一节内容已知 K0.676 step1.8/X&#xff08;x为细分值&#xff0c;1.8对…

【Leetcode】349. 两个数组的交集

题意 给定两个数组&#xff0c;编写一个函数来计算它们的交集。 说明&#xff1a; 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。 思路 这道题目&#xff0c;主要要学会使用一种哈希数据结构&#xff1a;unordered_set&#xff0c;这个数据结构可以解决…