Golang运行时错误:无效内存地址或空指针解引用 [SIGSEGV信号:段错误 code=0x1 addr=0x30 pc=0x7d65b6]
Golang运行时错误:无效内存地址或空指针解引用 [SIGSEGV信号:段错误 code=0x1 addr=0x30 pc=0x7d65b6] errorlog.txt
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x7d65b6]
goroutine 9 [running]:
github.com/gomodule/redigo/redis.(*Pool).waitVacantConn(0x7f67fc9e3c00?, {0x973598?, 0xc000024040?})
/build/sources/go/pkg/mod/github.com/gomodule/redigo@v1.8.9/redis/pool.go:357 +0x36
github.com/gomodule/redigo/redis.(*Pool).GetContext(0x0, {0x973598, 0xc000024040})
/build/sources/go/pkg/mod/github.com/gomodule/redigo@v1.8.9/redis/pool.go:200 +0x45
github.com/gomodule/redigo/redis.(*Pool).Get(...)
/build/sources/go/pkg/mod/github.com/gomodule/redigo@v1.8.9/redis/pool.go:186
此文件已被截断。显示原文
package main
import (
"fmt"
"gitlab.com/harish/calls/redis"
)
func main() {
此文件已被截断。显示原文
package redis
import (
"fmt"
"log"
"time"
"github.com/gomodule/redigo/redis"
)
此文件已被截断。显示原文
更多关于Golang运行时错误:无效内存地址或空指针解引用 [SIGSEGV信号:段错误 code=0x1 addr=0x30 pc=0x7d65b6]的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你的 main.go 文件是不是应该写成 RedisConn = redis.Setup()?我没看到 RedisConn 是在哪里被设置的。
更多关于Golang运行时错误:无效内存地址或空指针解引用 [SIGSEGV信号:段错误 code=0x1 addr=0x30 pc=0x7d65b6]的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这个错误是由于在 redis.go 文件中,RedisPool 变量在使用前没有被正确初始化导致的。从堆栈跟踪可以看出,在 pool.go:200 行调用 GetContext 方法时,接收器(pool 对象)的值为 0x0(nil)。
以下是问题分析和修复方案:
问题分析
在 redis.go 文件中,RedisPool 是一个全局变量:
var RedisPool *redis.Pool
但在代码中,这个变量可能在使用前没有被初始化,或者初始化失败。当调用 RedisPool.Get() 时,由于 RedisPool 是 nil,导致解引用空指针。
修复方案
1. 确保初始化 Redis 连接池
在 redis.go 中添加初始化函数,并确保在使用前调用:
package redis
import (
"fmt"
"log"
"time"
"github.com/gomodule/redigo/redis"
)
var RedisPool *redis.Pool
// InitRedisPool 初始化 Redis 连接池
func InitRedisPool(host, port, password string, db int) error {
RedisPool = &redis.Pool{
MaxIdle: 10,
MaxActive: 100,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
address := fmt.Sprintf("%s:%s", host, port)
c, err := redis.Dial("tcp", address)
if err != nil {
return nil, err
}
if password != "" {
if _, err := c.Do("AUTH", password); err != nil {
c.Close()
return nil, err
}
}
if _, err := c.Do("SELECT", db); err != nil {
c.Close()
return nil, err
}
return c, nil
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
if time.Since(t) < time.Minute {
return nil
}
_, err := c.Do("PING")
return err
},
}
// 测试连接
conn := RedisPool.Get()
defer conn.Close()
_, err := conn.Do("PING")
return err
}
// GetConn 安全获取连接
func GetConn() (redis.Conn, error) {
if RedisPool == nil {
return nil, fmt.Errorf("redis pool not initialized")
}
return RedisPool.Get(), nil
}
2. 在 main.go 中正确初始化
package main
import (
"fmt"
"log"
"gitlab.com/harish/calls/redis"
)
func main() {
// 初始化 Redis 连接池
err := redis.InitRedisPool("localhost", "6379", "", 0)
if err != nil {
log.Fatalf("Failed to initialize Redis pool: %v", err)
}
// 使用 Redis
conn, err := redis.GetConn()
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// 执行 Redis 操作
_, err = conn.Do("SET", "key", "value")
if err != nil {
log.Fatal(err)
}
value, err := redis.String(conn.Do("GET", "key"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Got value: %s\n", value)
}
3. 添加安全检查
在使用 RedisPool 的任何地方都添加 nil 检查:
func SomeFunction() error {
if redis.RedisPool == nil {
return fmt.Errorf("redis pool is not initialized")
}
conn := redis.RedisPool.Get()
defer conn.Close()
// ... 其他操作
return nil
}
关键点
- 全局变量初始化:确保
RedisPool在第一次使用前被正确初始化 - 错误处理:初始化函数应返回错误,调用方需要处理这些错误
- 延迟初始化:考虑使用
sync.Once确保只初始化一次:
var (
RedisPool *redis.Pool
once sync.Once
)
func InitRedisPoolOnce(host, port, password string, db int) error {
var initErr error
once.Do(func() {
initErr = InitRedisPool(host, port, password, db)
})
return initErr
}
这样修复后,可以避免空指针解引用错误,并确保 Redis 连接池在使用前已正确初始化。

