我不明白为什么在附加到另一个结构中的结构片段时会出现无效的内存地址混乱。
运行代码时出现以下错误。
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x400d5f]
goroutine 3 [running]:
main.Pairs.CollectTickers(0x0, 0x0)
test.go:32 +0x15f
created by main.main
test.go:42 +0x42
goroutine 1 [sleep]:
time.Sleep(0x174876e800)
/usr/lib/go/src/pkg/runtime/ztime_linux_amd64.c:19 +0x2f
main.main()
test.go:43 +0x57
exit status 2
此代码产生以下错误:
package main
import (
"fmt"
"sync"
"time"
)
var PairNames = []string{ "kalle", "kustaa", "daavid", "pekka" }
type Data struct {
a int
b int
}
type Tickers struct {
Tickers []Data
}
type Pairs struct {
Pair map[string]*Tickers
Mutex sync.Mutex
}
func (pairs Pairs) CollectTickers() {
PairCount := len(PairNames)
for x := 0; x <= 1000; x++ {
for i := 0; i < PairCount-1; i++ {
var data Data
data.a = i * x
data.b = i + x
pairs.Mutex.Lock()
pairs.Pair[PairNames[i]].Tickers = append(pairs.Pair[PairNames[i]].Tickers, data)
pairs.Mutex.Unlock()
fmt.Printf("a = %v, b = %v\r\n", data.a, data.b)
}
}
}
func main() {
var pairs Pairs
go pairs.CollectTickers()
time.Sleep(100 * time.Second)
}
答案 0 :(得分:4)
错误发生在:
pairs.Pair[PairNames[i]].Tickers = append(pairs.Pair[PairNames[i]].Tickers, data)
Tickers
是一个nil指针,因为你还没有分配Tickers实例。
我不确定这是否符合您的意图,但它可以编译并成功运行。
package main
import (
"fmt"
"sync"
"time"
)
var PairNames = []string{"kalle", "kustaa", "daavid", "pekka"}
type Data struct {
a int
b int
}
type Tickers struct {
Tickers []Data
}
type Pairs struct {
Pair map[string]*Tickers
Mutex sync.Mutex
}
func (pairs Pairs) CollectTickers() {
PairCount := len(PairNames)
for x := 0; x <= 1000; x++ {
for i := 0; i < PairCount-1; i++ {
var data Data
data.a = i * x
data.b = i + x
pairs.Mutex.Lock()
name := PairNames[i]
if t, ok := pairs.Pair[name]; ok {
t.Tickers = append(t.Tickers, data)
} else {
pairs.Pair[name] = &Tickers{
Tickers: []Data{data},
}
}
pairs.Mutex.Unlock()
fmt.Printf("a = %v, b = %v\r\n", data.a, data.b)
}
}
}
func main() {
var pairs = Pairs{
Pair: make(map[string]*Tickers),
}
go pairs.CollectTickers()
time.Sleep(1 * time.Second)
}
答案 1 :(得分:2)
pairs.Pair[PairNames[i]]
的值为nil
,因为PairNames[i]
地图中没有pairs.Pair
的条目,nil
是{{1}的零值}}。因此,*Tickers
是取消引用pairs.Pair[PairNames[i]].Tickers
指针的无效尝试。
The Go Programming Language Specification
对于地图类型M:
nil
该语言现在指出,出于安全原因,某些用途 nil指针保证会引发运行时恐慌。