Golang错误解析"runtime error: invalid memory address or nil pointer dereference"

概述

从刚上手golang时就经常遇到这个错误, 三个月之后对golang有些了解, 开始理清一下原因.

问题原因

var p *Obj

某个指针变量声明之后, 还没有经过赋值时默认指向nil, 直接调用指针就会报错

runtime error: invalid memory address or nil pointer dereference

示例

package main

import(
	"fmt"
	"math"
)

type Point struct {
    X, Y float64
}

func (p *Point) Abs() float64 {
    return math.Sqrt(p.X*p.X + p.Y*p.Y)
}

func main() {
	var p Point //正常
    fmt.Println(p) //输出 {0 0}
    var nilPtr *Point //报错
    fmt.Println(nilPtr) //<nil>
    var newPtr *Point = new(Point)
    fmt.Println(newPtr) //&{0 0}

	//调用Abs()
    fmt.Println(p.Abs()) //正常
    // fmt.Println(nilPtr.Abs()) //报错
    // fmt.Println(newPtr.Abs()) //正常
}
代码解释
  • Point结构有一个Abs()方法, 在go中method的receiver为"*Point"指针类型时, Point对象和对象指针皆可调用Abs()方法.
  • var p Point 声明, p被初始化, 并赋初始值, 可调用Abs()
  • var nilPtr *Point声明, nilPtr指向nil, 未初始化, 不可调用Abs()
  • var newPtr *Point = new(Point)声明, newPtr 指向一个被初始化的Point 对象, 可调用Abs().

实际出错场景

package main

import(
	"fmt"
	"net/http"
)

var HttpServer *http.Server

func StartHttpServer() {
	HttpServer := newHttpServer() //改为 HttpServer = newHttpServer()正常
	...
}


func StopHttpServer() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := HttpServer.Shutdown(ctx); err != nil { //报错位置
       log.Logger.Error("shutdown http server fail", zap.Error(err))
	}
}
func main(){
	StartHttpServer()
	...
	StopHttpServer()
}
代码解释
  • HttpServer为全局变量, 主函数调用StartHttpServer()完成初始化. StopHttpServer()中直接使用全局变量HttpServer.
  • 报错原因: HttpServer.Shutdown()调用报错,访问了nil指针.
  • 因为StartHttpServer()中使用了":="进行初始化, 会导致StartHttpServer中的HttpServer是一个新的变量, 且仅在作用在函数体内.
  • StopHttpServer()中调用逻辑相当于
var HttpServer *http.Server //当前指向nil
HttpServer.Shutdown()

总结

基本上都是

var HttpServer *http.Server

类似这样的声明语句但是没有完成初始化就调用对象方法或者访问对象变量, 检查代码中是否有这类问题即可.

  • 15
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 根据你提供的引用内容,你遇到的问题是一个RuntimeError: selected index k out of range的错误。然而,根据提供的引用内容,我无法确定这个错误的具体原因。可能是由于代码中的某些逻辑错误导致了索引超出范围。为了解决这个问题,你可以尝试以下几个步骤: 1. 检查代码中与索引相关的部分,确保没有超出索引范围的情况发生。你可以使用调试工具或打印语句来跟踪代码执行过程,找出导致错误的具体位置。 2. 确保你的数据集或输入数据的维度与代码中的索引范围相匹配。如果数据集的大小与代码中的索引范围不一致,可能会导致索引超出范围的错误。 3. 检查你的代码中是否存在其他可能导致索引超出范围的逻辑错误,例如循环条件或条件语句中的错误。 如果以上步骤都没有解决问题,我建议你提供更多的代码和错误信息,以便我能够更准确地帮助你解决这个问题。 #### 引用[.reference_title] - *1* [pytorch loss.backward() 报错RuntimeError: select(): index 0 out of range for tensor of size [0, 1]...](https://blog.csdn.net/qq_45475106/article/details/122407163)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Tidb 查询sql 报runtime error: index out of range [-1]错误](https://blog.csdn.net/zanpengfei/article/details/125876124)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [sentinel-golang,再linux上运行报错:runtime error: index out of range [-6]](https://blog.csdn.net/u014686399/article/details/128632100)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值