首页 文章

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

提问于
浏览
10

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

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 为零?如果是这样,怎么样?

注意:哈希定义为字符串

1 回答

  • 14

    这意味着 Attributes 被调用接收器 m 作为 nil .

    原则上可以使用 nil 接收器调用方法(如果它们检查 nil ,这甚至可能很有用) - 请参阅here - 但是这个特定的方法 Attributes() 不是用 nil 接收器调用的,因为 m 在没有 nil 的情况下被取消引用校验 . 这是(使用 nil receiver 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
    

相关问题