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

这篇具有很好参考价值的文章主要介绍了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 超出范围时,函数将立即返回,避免继续执行可能导致空指针错误的代码。

Go invalid memory address or nil pointer dereference错误 空指针问题,golang,开发语言,后端Go invalid memory address or nil pointer dereference错误 空指针问题,golang,开发语言,后端文章来源地址https://www.toymoban.com/news/detail-754737.html

到了这里,关于Go invalid memory address or nil pointer dereference错误 空指针问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • tp8 升级TP框架版本,同时网站打不开,错误代码 ERR_ADDRESS_INVALID,启动内置服务器 运行PHP命令php think run 输出结果是空白

    环境:windows11  phpstudy_pro  thinkphp8.0 php8.2.9   进入composer : 选择composer,再选择对应网站的PHP版本, 启动内置服务器 按上面操作,发现输出结果是空白,没有任何东西 三、启用VSCODE的xdebug调试 在VSCODE中启用调试F5,在think文件中打断点 全部勾上 一直一步一步往下走,发现

    2024年01月22日
    浏览(83)
  • Go 接口:nil接口为什么不等于nil?

    本文主要内容:深入了解接口类型的运行时表示层。 目录 Go 接口:nil接口为什么不等于nil? 一、Go 接口的地位 二、接口的静态特性与动态特性 2.1 接口的静态特性与动态特性介绍 2.2 “动静皆备”的特性的好处 三、nil error 值 != nil 四、接口类型变量的内部表示 第一种:nil 接

    2024年02月05日
    浏览(68)
  • thinkphp8 - tp8升级框架版本后网站打不开,网页提示错误代码:ERR_ADDRESS_INVALID(启动内置服务器运行php think run命令返回的结果是空白解决,但静态网站能打开

    在windows环境+ phpstudy(小皮面板)本地中,升级TP框架发现php网站打不开了,并且网页中间提示错误代码ERR_ADDRESS_INVALID,神奇的是静态网站可以正常打开。 这个问题已经完美解决。 其实,

    2024年01月25日
    浏览(65)
  • Go 语言 nil 空值

    在 Go 语言中, nil 是一个预定义的标识符,用于表示某些类型的零值或空值。 nil 在 Go 语言中可以表示以下几种类型的零值或空值: 指针类型:表示一个指向空地址的指针,即指针不指向任何有效的内存地址。 接口类型:表示一个空接口,即接口没有关联任何值。 函数类型

    2024年02月11日
    浏览(37)
  • Go 空切片与nil切片

    在 Go 语言中,空切片和 nil 切片是两种不同的概念。 空切片是一个长度和容量都为 0 的切片。你可以通过 make 函数或者切片字面量来创建一个空切片,例如 s := make([]int, 0) 或者 s := []int{}。 空切片不是 nil,即 s != nil。 空切片已经分配了内存空间,所以你可以直接向空切片中

    2024年02月20日
    浏览(36)
  • free(): invalid pointer arm环境O2优化下string free异常分析

    近期,ARM开发环境中出现过一次free(): invalid pointer的coredump问题,其根本原因是函数中的string对象内存被踩。在此处做下记录。 下面的程序是自己写的模拟程序。

    2024年02月08日
    浏览(39)
  • Go语言中的空和nil

    Go语言中的空和nil 在 Go 语言中,\\\"空\\\"和\\\"nil\\\"是两个不同的概念,分别适用于不同的数据类型和用途。 在 Go 中,每种数据类型都有一个默认的零值,也被称为\\\"空\\\"值。这是在创建变量但未显式初始化时自动分配给变量的值。空值对于不同类型的变量来说是不同的,例如: 数值类

    2024年02月13日
    浏览(92)
  • Go 空切片 VS nil切片

    在 Go 语言中,空切片和 nil 切片是两种不同的概念。 空切片是一个长度和容量都为 0 的切片。你可以通过 make 函数或者切片字面量来创建一个空切片,例如 s := make([]int, 0) 或者 s := []int{}。 空切片不是 nil,即 s != nil。 空切片已经分配了内存空间,所以你可以直接向空切片中

    2024年02月20日
    浏览(49)
  • go数据类型-空结构体、空接口、nil

    有经验的开发人员都知道,所有的空结构体是指向一个 zerobase的地址,而且大小为0 一般用来作结合map作为set 或者 在channel中 传递信号。 能看到当一个空结构体中,包含了其他类型的变量,就不指向 zerobase。 go中的接口都是隐式的,增加的封装的灵活性,也为阅读源码增加了

    2024年02月05日
    浏览(55)
  • 【开发掉坑】go 中 interface 的 nil 判断

    今天介绍下 go 中的 interface(any) 的 nil 判断,项目中遇到的一个小问题,知识遗忘了,再做个记录。 最近在合作开发项目的过程中,发现小伙伴写了一段代码,示意代码如下: 输出: 由于该代码仓库是为了让其他项目使用,基于之前的老项目抽离出来的,老项目的结构体和新

    2024年01月20日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包