英文:
Getting unexpected fault address error when unmarshalling json from bolt database in external function
问题
我目前正在处理在Go语言中从Bolt数据库中存储/检索字符的问题。我编写了以下函数来检索存储的每个字符,它运行良好。
// 这个函数运行良好
func GetAllCharacters() []Character {
var charList []Character
var char Character
db, err := bolt.Open("./savedata/database.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte("DB")).Bucket([]byte("Characters")).Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
err := json.Unmarshal(v, &char)
if err != nil {
log.Fatal(err)
}
charList = append(charList, char)
}
return nil
})
if err != nil {
log.Fatal(err)
}
return charList
}
然后,我想整理一下代码,将函数的一部分移到另一个文件中,像这样:
utils文件:
package utils
func GetAllCharactersFromDB() [][]byte {
var charList [][]byte
db, err := bolt.Open("./savedata/database.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte("DB")).Bucket([]byte("Characters")).Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
charList = append(charList, v)
}
return nil
})
if err != nil {
log.Fatal(err)
}
return charList
}
main文件:
func GetAllCharacters() []Character {
var charList []Character
var char Character
allChars := utils.GetAllCharactersFromDB()
for _, v := range allChars {
err := json.Unmarshal(v, &char)
if err != nil {
log.Fatal(err)
}
charList = append(charList, char)
}
return charList
}
现在,当我尝试运行这段代码时,我得到了一个我无法理解的加密错误消息:
unexpected fault address 0x20d5607405f
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0x20d5607405f pc=0xa4ba35]
goroutine 1 [running]:
runtime.throw({0xa93ef9, 0x20d30d50108})
C:/Program Files/Go/src/runtime/panic.go:1198 +0x76 fp=0xc0001096a0 sp=0xc000109670 pc=0x9b4b16
runtime.sigpanic()
C:/Program Files/Go/src/runtime/signal_windows.go:260 +0x10c fp=0xc0001096e8 sp=0xc0001096a0 pc=0x9c606c
encoding/json.checkValid({0x20d5607405f, 0x27a, 0x1}, 0xc00011c0b8)
C:/Program Files/Go/src/encoding/json/scanner.go:32 +0xb5 fp=0xc000109710 sp=0xc0001096e8 pc=0xa4ba35
encoding/json.Unmarshal({0x20d5607405f, 0xac2ec0, 0xc000006010}, {0xa8b400, 0xc000118120})
C:/Program Files/Go/src/encoding/json/decode.go:101 +0x5a fp=0xc000109758 sp=0xc000109710 pc=0xa3cc9a
github.com/my_name/gotestgame/game.GetAllCharacters()
C:/Users/my_name/Documents/Golang/simplegame/game/characters.go:164 +0xcc fp=0xc000109808 sp=0xc000109758 pc=0xa63b4c
github.com/my_name/gotestgame/game.Leaderboard()
C:/Users/my_name/Documents/Golang/simplegame/game/level.go:125 +0xab fp=0xc000109d20 sp=0xc000109808 pc=0xa6782b
github.com/my_name/gotestgame/game.MainMenu()
C:/Users/my_name/Documents/Golang/simplegame/game/menu.go:58 +0x3ba fp=0xc000109f60 sp=0xc000109d20 pc=0xa699da
main.main()
C:/Users/my_name/Documents/Golang/simplegame/main.go:16 +0x4a fp=0xc000109f80 sp=0xc000109f60 pc=0xa6d4ea
runtime.main()
C:/Program Files/Go/src/runtime/proc.go:255 +0x217 fp=0xc000109fe0 sp=0xc000109f80 pc=0x9b70d7
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000109fe8 sp=0xc000109fe0 pc=0x9df7e1
exit status 2
有人能告诉我为什么新的方法不起作用吗?我该怎么做才能让它工作?我认为json.Unmarshal
在两种情况下都会解组相同的[]byte
,我错了吗?当我在GetAllCharactersFromDB()
函数中打印string(v)
的内容时,我得到了一个可读的JSON字符串。虽然第一个代码片段可以工作,但我困扰于无法弄清楚为什么第二种方法不起作用。对不起,如果这是一个愚蠢的问题,我对Go语言还不太熟悉。
编辑:
回应评论,这是一个Character
的样子:
type Character struct {
Name string `json:"name"`
Hardcore bool `json:"hardcore"`
Default bool `json:"default"`
Level int `json:"level"`
XP int `json:"xp"`
Class string `json:"class"`
Max_HP int `json:"max_hp"`
Current_HP int `json:"current_hp"`
Strength int `json:"str"`
Dexterity int `json:"dex"`
Intelligence int `json:"int"`
Gold int `json:"gold"`
Weapon Weapon `json:"weapon"`
Items []Item `json:"items"`
}
这是存储的数据的样子:
{"name":"Test1","hardcore":true,"default":true,"level":1,"xp":1,"class":"Barbarian","max_hp":150,"current_hp":150,"str":30,"dex":15,"int":5,"gold":0,"weapon":{"Name":"Rusty Club","Description":"Starter Weapon for the Barbarian.","Rarity":{"Common":1,"Uncommon":0,"Rare":0,"Epic":0,"Legendary":0},"LowAttack":15,"HighAttack":40,"AttackSpeed":1.2,"CritChance":5,"Accuracy":95,"Range":10,"ReqStr":15,"ReqDex":5,"ReqInt":0,"BuyPrice":30,"SellPrice":1},"items":[{"Name":"Small Healing Potion","Description":"Heals you for 20 HP","Tag":"Heal","Rarity":{"Common":1,"Uncommon":0,"Rare":0,"Epic":0,"Legendary":0},"BuyPrice":25,"SellPrice":1}]}
英文:
I am currently working on storing/retrieving characters from a Bolt Database in Go.
I wrote this function here to retrieve every character stored and it worked fine.
//this works fine
func GetAllCharacters() []Character {
var charList []Character
var char Character
db, err := bolt.Open("./savedata/database.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte("DB")).Bucket([]byte("Characters")).Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
err := json.Unmarshal(v, &char)
if err != nil {
log.Fatal(err)
}
charList = append(charList, char)
}
return nil
})
if err != nil {
log.Fatal(err)
}
return charList
}
Then I wanted to clean up my code a bit and moved a part of the function to a different file, like this:
utils file:
package utils
func GetAllCharactersFromDB() [][]byte {
var charList [][]byte
db, err := bolt.Open("./savedata/database.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte("DB")).Bucket([]byte("Characters")).Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
charList = append(charList, v)
}
return nil
})
if err != nil {
log.Fatal(err)
}
return charList
}
main file:
func GetAllCharacters() []Character {
var charList []Character
var char Character
allChars := utils.GetAllCharactersFromDB()
for _, v := range allChars {
err := json.Unmarshal(v, &char)
if err != nil {
log.Fatal(err)
}
charList = append(charList, char)
}
return charList
}
And now when I try to run this code, I get a this cryptic error message that I cannot really decrypt:
unexpected fault address 0x20d5607405f
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0x20d5607405f pc=0xa4ba35]
goroutine 1 [running]:
runtime.throw({0xa93ef9, 0x20d30d50108})
C:/Program Files/Go/src/runtime/panic.go:1198 +0x76 fp=0xc0001096a0 sp=0xc000109670 pc=0x9b4b16
runtime.sigpanic()
C:/Program Files/Go/src/runtime/signal_windows.go:260 +0x10c fp=0xc0001096e8 sp=0xc0001096a0 pc=0x9c606c
encoding/json.checkValid({0x20d5607405f, 0x27a, 0x1}, 0xc00011c0b8)
C:/Program Files/Go/src/encoding/json/scanner.go:32 +0xb5 fp=0xc000109710 sp=0xc0001096e8 pc=0xa4ba35
encoding/json.Unmarshal({0x20d5607405f, 0xac2ec0, 0xc000006010}, {0xa8b400, 0xc000118120})
C:/Program Files/Go/src/encoding/json/decode.go:101 +0x5a fp=0xc000109758 sp=0xc000109710 pc=0xa3cc9a
github.com/my_name/gotestgame/game.GetAllCharacters()
C:/Users/my_name/Documents/Golang/simplegame/game/characters.go:164 +0xcc fp=0xc000109808 sp=0xc000109758 pc=0xa63b4c
github.com/my_name/gotestgame/game.Leaderboard()
C:/Users/my_name/Documents/Golang/simplegame/game/level.go:125 +0xab fp=0xc000109d20 sp=0xc000109808 pc=0xa6782b
github.com/my_name/gotestgame/game.MainMenu()
C:/Users/my_name/Documents/Golang/simplegame/game/menu.go:58 +0x3ba fp=0xc000109f60 sp=0xc000109d20 pc=0xa699da
main.main()
C:/Users/my_name/Documents/Golang/simplegame/main.go:16 +0x4a fp=0xc000109f80 sp=0xc000109f60 pc=0xa6d4ea
runtime.main()
C:/Program Files/Go/src/runtime/proc.go:255 +0x217 fp=0xc000109fe0 sp=0xc000109f80 pc=0x9b70d7
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000109fe8 sp=0xc000109fe0 pc=0x9df7e1
exit status 2
Can anyone tell me why the new approach does not work? And what I could do to make it work? I thought the json.Unmarshal
would be unmarshalling the same []byte
in both cases, or am I wrong there? When I print out the content of string(v)
in the GetAllCharactersFromDB()
function I get a readable json string. It is not very urgent as the first code snippet works, but it bothers me that I cannot figure out why the second approach does not work. Sorry if this is a stupid question, I am fairly new to Go.
EDIT:
In response to the comment, heres how a Character
looks:
type Character struct {
Name string `json:"name"`
Hardcore bool `json:"hardcore"`
Default bool `json:"default"`
Level int `json:"level"`
XP int `json:"xp"`
Class string `json:"class"`
Max_HP int `json:"max_hp"`
Current_HP int `json:"current_hp"`
Strength int `json:"str"`
Dexterity int `json:"dex"`
Intelligence int `json:"int"`
Gold int `json:"gold"`
Weapon Weapon `json:"weapon"`
Items []Item `json:"items"`
}
And here's how the data stored looks:
{"name":"Test1","hardcore":true,"default":true,"level":1,"xp":1,"class":"Barbarian","max_hp":150,"current_hp":150,"str":30,"dex":15,"int":5,"gold":0,"weapon":{"Name":"Rusty Club","Description":"Starter Weapon for the Barbarian.","Rarity":{"Common":1,"Uncommon":0,"Rare":0,"Epic":0,"Legendary":0},"LowAttack":15,"HighAttack":40,"AttackSpeed":1.2,"CritChance":5,"Accuracy":95,"Range":10,"ReqStr":15,"ReqDex":5,"ReqInt":0,"BuyPrice":30,"SellPrice":1},"items":[{"Name":"Small Healing Potion","Description":"Heals you for 20 HP","Tag":"Heal","Rarity":{"Common":1,"Uncommon":0,"Rare":0,"Epic":0,"Legendary":0},"BuyPrice":25,"SellPrice":1}]}
答案1
得分: 2
请尝试将以下行替换为:
charList = append(charList, v)
替换为
vc := make([]byte, len(v))
copy(vc,v)
charList = append(charList, vc)
英文:
Please try to replace the following line:
charList = append(charList, v)
with
vc := make([]byte, len(v))
copy(vc,v)
charList = append(charList, vc)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论