go - 意外的无效内存地址或 nil 指针取消引用

标签 go

我收到无效内存地址的运行时错误。

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

goroutine 1192592 [running]:
panic(0x793540, 0xc420010040)
#011/usr/local/go/src/runtime/panic.go:500 +0x1a1
foobar/sd.(*Channel).Attributes(0x0, 0xc420110101, 0xc42278f9b0, 0x9)
#011/home/app/go/src/foobar/sd/channel.go:36 +0x54

channel.go 看起来像这样:

35 func (m *Channel) Attributes() (*ChannelAttrs, error) {
36    redisHash := "sd:channels:" + m.hash
37
38    rc := m.ctx.RedisPool.Get()
39    values, err := redis.Values(rc.Do("HGETALL", redisHash))
40    rc.Close()
41    if err != nil {
42        return nil, err
43    }
44    attrs := ChannelAttrs{}
45    redis.ScanStruct(values, &attrs)
46    return &attrs, nil
47 }

第 36 行怎么可能导致这种情况? m 是否有可能为零?如果有,怎么做?

注意:哈希定义为字符串

最佳答案

这意味着 Attributes 被调用,接收者 mnil

原则上可以用 nil 接收器调用方法(如果他们检查 nil,这甚至可能很有用) - 参见 here - 但是这个特殊的方法 Attributes() 不是设计成用 nil 接收器调用的,因为 m 是在没有 的情况下被取消引用的无 检查。这(使用 nil 接收器 m 调用的方法)是您的调用代码中发生的事情。

查看简化示例 on the playground here ,并注意注释掉 + m.hash 使整个事情正常工作,如 here .

代码如下:

package main

import (
    "fmt"
)

type Channel struct {
    hash string
}

func (m *Channel) Attributes() {
    r := "x" + m.hash
    fmt.Println(r)
}

func main() {
    var c *Channel
    c.Attributes()
}

其输出为:

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

goroutine 1 [running]:
panic(0x102360, 0x1040a038)
    /usr/local/go/src/runtime/panic.go:500 +0x720
main.(*Channel).Attributes(0x0, 0x104000f0)
/tmp/sandbox285779060/main.go:12 +0x131
main.main()
    /tmp/sandbox285779060/main.go:18 +0x20

关于go - 意外的无效内存地址或 nil 指针取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40201209/

相关文章:

go - gRPC 连接问题 : How to figure out if it is the server or the client?

go - 调用中的参数过多

go - 类型声明中的匿名字段?

go - SIGKILL 以外的信号不会在 Windows 上终止进程

multithreading - 合并 channel 中的项目

docker - 尝试在golang中使用exec.Command()执行docker pull时,我看不到进度条

json - 在golang中解码数组json

arrays - go程序比较两个数组并将匹配的元素存储在golang中的第三个数组中

google-app-engine - App Engine 部署到不是 project_id.appspot.com 的地方

go - 如何检查文本文件是否包含整个单词?