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

news2025/3/11 13:07:40

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 超出范围时,函数将立即返回,避免继续执行可能导致空指针错误的代码。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea 将分支的代码合并到master

idea 将分支的代码合并到master 1. 首先签出到自己的分支 (自己的分支是自己写的代码&#xff0c;需要合并到master分支去&#xff09; 2. 然后选中master分支&#xff0c;右键选择 签出并变基到“feature_SC” &#xff0c;完成之后master分支中就已经是完整的代码了。 当…

Vue、fabricJS 画布实现自由绘制折线

作者GitHub&#xff1a;https://github.com/gitboyzcf 有兴趣可关注 Vue3代码&#xff0c;Vue2相似改吧改吧 前言 Fabric.js Fabric.js&#xff08;英文官网&#xff09;是一个强大而简单的 Javascript HTML5画布库&#xff08;也就是针对canvas进行的封装操作&#xff0c;使…

【面试经典150 | 位运算】二进制求和

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;模拟 其他语言c 写在最后 Tag 【二进制】【位运算】 题目来源 67. 二进制求和 题目解读 以二进制字符串的形式返回两个二进制字符串的和。 解题思路 看到这个题目首先想到的方法可能是先把二进制字符转化成 int 型数…

wvp-gb28181-pro接入海康摄像头

网络-高级配置-平台接入 sip服务器信息默认参数如下&#xff0c;一键安装wvp完成之后默认就是这样的参数 设置项 设置值 平台接入方式 28181 本地sip端口 5060 传输协议 tcp、udp&#xff08;外网的话我建议还是用tcp&#xff09; 启用 勾选 协议版本 GB/T28181-201…

使用Matplotlib绘画3D图时运行不出结果,也不报错,图片是空白 !!

1.问题&#xff1a; 我使用如下代码运用matplotlib中的Axes3D绘画3D图&#xff0c;但是运行出来的结果是空白。 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D #导入3D包 fig plt.figure() #窗口 #ax Axes3D(fig) # X, Y …

CSC公派遭美德拒签|计算机专业老师终赴意大利都灵理工大学访学

C老师拟申报CSC访学项目&#xff0c;希望先申请美国&#xff0c;并做好了一旦拒签再申请其它国家的心理准备。我们先用普渡大学的邀请函助其申报CSC&#xff0c;并顺利获批&#xff0c;但不出所料地被美国拒签了&#xff1b;很快又申请到德国奥芬堡应用技术大学&#xff0c;但不…

Mysql数据库 8.SQL语言 外键约束

一、外键约束 外键约束——将一个列添加外键约束与另一张表的主键&#xff08;唯一列&#xff09;进行关联之后&#xff0c;这个外键约束的列添加的数据必须要在关联的主键字段中存在 案例 创建原则&#xff1a;先创建不含外键的表也就是班级表 添加外键的方式 一般使用第一…

Go 跟踪函数调用链,理解代码更直观

Go 跟踪函数调用链&#xff0c;理解代码更直观 文章目录 Go 跟踪函数调用链&#xff0c;理解代码更直观一、引入二、自动获取所跟踪函数的函数名三、增加 Goroutine 标识四、让输出的跟踪信息更具层次感五、利用代码生成自动注入 Trace 函数5.1 将 Trace 函数放入一个独立的 mo…

day2 ARM基础

.text .globl _start _start:mov r0,#0 mov r1,#0 addfunc:add r0,r0,#1 r0自增1adds r1,r1,r0 R1实现1~100累加cmp r0,#100 判断r0是否到100bleq loop r0等于100 进入死循环 blne addfunc r0等于100跳转至循环累加 loop:b loopstop:b stop.end 【汇编…

win10语言切换调整为像win7一样,设置纯英文键盘切换,使用ctrol+shift切换键盘

文章目录 引入键盘布局说明安装美式键盘去掉微软键盘&#xff0c;修改布局切换快捷键最终效果 引入 我们在玩游戏或者写代码的时候&#xff0c;常常需要使用shift键&#xff0c;而输入法的shift键常常是中英切换按键&#xff0c;这就让人非常不爽了&#xff0c;这里仿照在win7…

JSP(Java Server Pages)

JSP 即 Java服务端页面。 其中既可以定义HTML、JS、CSS等静态内容&#xff0c;还可以定义Java代码的动态内容。也就是JSPHTML Java。 JSP代码简单例子&#xff1a; <html><head><title>Title</title></head><body><h1>JSP,Hello…

java入门,Map<? extends String, ?>

一、前言 是不是平时写业务代码的时候很少用到这个写法&#xff1a;Map<? extends String, ?>&#xff0c;这是Map类型&#xff0c;Map的键是? extends String 类型&#xff0c;值是?。为什么不是我们平时写的Map< String, Object>&#xff0c;这种写法有什么好…

Docker-compose容器群集编排管理工具

目录 Docker-compose 1、Docker-compose 的三大概念 2、YAML文件格式及编写注意事项 1&#xff09;使用 YAML 时需要注意下面事项 2&#xff09;ymal文件格式 3&#xff09;json格式 3、Docker Compose配置常用字段 4、Docker-compose的四种重启策略 5、Docker Compose…

【系统集成项目管理工程师】——5.计算

沟通&#xff1a;沟通渠道数n(n-1)/2&#xff0c;n代表人数 风险 三角分布: 期望[乐观 (小值) 最可能 (中值) 悲观 (大值) ]/3 贝塔分布:期望[乐观(小值) 4*最可能(中值) 悲观(大值) ]/6 标准差[悲观(大值)-乐观(小值) ]/6 方差[悲观 (大值) -乐观 (小值) ]^2/36 概率计算: 士…

DeepLearning - 余弦退火热重启学习率 CosineAnnealingWarmRestartsLR

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/134249925 CosineAnnealingWarmRestartsLR&#xff0c;即 余弦退火热重启学习率&#xff0c;周期性修改学习率的下降和上升&#xff0c;间隔幅度逐…

SRAM之ECC检测机制

文章目录 前言一、SRAM简介1. RAM介绍2. SRAM介绍3. SRAM和DRAM的区别4. S32K146系列的SRAM5. LMEM 二、ECC1. EIM模块简介2. 操作步骤1&#xff09;定义反转的读取总线上的Bit&#xff08;Word1&#xff09;2&#xff09;定义反转的CheckBit总线上的Bit&#xff08;Word0&…

Sui浏览器现支持查看已验证的Move源代码

Sui浏览器现在包含了Sui框架包的源代码视图&#xff0c;这是一个备受欢迎的功能。这个新的“已验证源代码&#xff08;Source Verified&#xff09;”选项卡位于现有的“字节码&#xff08;Bytecode&#xff09;”选项卡旁边&#xff0c;使开发人员可以点击查看以下包的源代码&…

SBOM 指南: 是什么及其作用

在软件开发的动态格局中&#xff0c;过去十年见证了两次重新定义了行业轨迹的变革性转变。首先是广泛采用开源软件组件&#xff0c;为开发人员提供大量预先构建的模块&#xff0c;以简化他们的工作。第二个是与DevOps文化的拥抱&#xff0c;自动化和加速软件构建和交付过程。总…

UE5——源码阅读——8——引擎预初始化

初始化文本本地化 执行平台特定的初始化内容 执行应用程序的特定预初始化 将当前的工作目录设置为可执行的目录 处理命令行选项 启用内存保护&#xff08;根据命令行是否启用内存保护&#xff09; 是否启用UE5内存管理的炼狱测试 是否启用UE5内存中有问题的测试 添加bu…

sql中的加减乘除

自学SQL网(教程 视频 练习全套)