英文:
Go memory address changing
问题
我非常新手Go语言,所以请谅解。我正在尝试通过Go与我的QNAP NAS进行交互。到目前为止,我可以登录,但无法退出。似乎qnap
的内存地址发生了变化。
这段代码打印如下内容:
0xc042060020
Logged in with SID: jli2wt7t
0xc042060020
0xc042004028
我不确定为什么在Logout
方法之前内存地址会发生变化。
我得到了以下错误:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x40 pc=0x5ed063]
goroutine 1 [running]:
main.(*QNAP).Logout(0xc04204a780, 0x0, 0x0, 0x0, 0x0)
C:/Users/redacted/test.go:85 +0x303
main.main()
C:/Users/redacted/test.go:115 +0x44e
exit status 2
英文:
I am very new to go, so please bear with me here. I am trying to interact with my QNAP NAS through go. So far I can log in, but not back out. It seems like the memory address of qnap
changes:
package main
import (
"net/url"
"fmt"
"net/http"
"encoding/base64"
"io/ioutil"
"encoding/xml"
"errors"
)
// QNAP REST API
type QNAPAPI struct {
Login,
Logout,
SysReq,
MiscAct,
MyCloud string
}
// QNAP NAS info
type QNAP struct {
URI, Username, Password, SID string
Client *http.Client
API QNAPAPI
}
// Assign API endpoints to struct
func initializeQNAPApi(API *QNAPAPI) QNAPAPI {
API.Login = "/cgi-bin/authLogin.cgi"
API.Logout = "/cgi-bin/authLogout.cgi"
API.SysReq = "/cgi-bin/sys/sysRequest.cgi"
API.MiscAct = "/cgi-bin/misc/misc_action.cgi"
API.MyCloud = "/cgi-bin/my_cloud/cloudRequest.cgi"
return *API
}
// Login to NAS
func (q *QNAP) Login() (string, error) {
// Match fields in XML
type LoginResponse struct {
AuthPassed int `xml:"authPassed"`
SID string `xml:"authSid"`
}
// Create data structure to bind XML to
loginResponse := LoginResponse{}
// Prepare POST headers
postData := url.Values{
"user": {q.Username},
"serviceKey": {"1"},
"pwd": {base64.StdEncoding.EncodeToString([]byte(q.Password))},
}
res, err := q.Client.PostForm(q.URI + q.API.Login, postData)
if err != nil {
return "", err
}
defer res.Body.Close()
responseData, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", err
}
xml.Unmarshal(responseData, &loginResponse)
if loginResponse.AuthPassed == 1 {
q.SID = loginResponse.SID
return loginResponse.SID, nil
}
return "", errors.New("Unable to login!")
}
// Logout from NAS
func (q *QNAP) Logout() (string, error) {
fmt.Println(&q)
postData := url.Values{
"logout": {"1"},
"sid": {q.SID},
}
// PROBLEM HERE???
res, err := q.Client.PostForm(q.URI + q.API.Logout, postData)
defer res.Body.Close()
fmt.Println(err)
fmt.Println(res)
responseData, err := ioutil.ReadAll(res.Body)
fmt.Println(err)
fmt.Println(string(responseData))
return "x", nil
}
func main() {
httpClient := &http.Client{}
qnap := &QNAP{
URI: "http://redacted.myqnapcloud.com:8080",
Username: "MyUserName",
Password: "MyPassword",
Client: httpClient,
API: initializeQNAPApi(&QNAPAPI{}),
}
fmt.Println(&qnap)
sid, err := qnap.Login()
if err != nil {
fmt.Println(err)
}
fmt.Printf("Logged in with SID: %s\n", sid)
// MEMORY ADDRESS CHANGES - WHY???
fmt.Println(&qnap)
qnap.Logout()
}
This code prints the following:
0xc042060020
Logged in with SID: jli2wt7t
0xc042060020
0xc042004028
I am not sure why the address changes right before the Logout
method.
I get the following error:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x40 pc=0x5ed063]
goroutine 1 [running]:
main.(*QNAP).Logout(0xc04204a780, 0x0, 0x0, 0x0, 0x0)
C:/Users/redacted/test.go:85 +0x303
main.main()
C:/Users/redacted/test.go:115 +0x44e
exit status 2
答案1
得分: 3
&
给出了一个变量的地址。在你的 Logout
函数中,&q
给出了 q
的地址,而 q
是一个局部变量。而该局部变量的值本身是一个地址,因为 q
本身是一个指针(指向类型为 QNAP
的结构体)。打印出的内存地址不同只是一个误导,你的空指针解引用才是真正的问题。如果你想要相同的地址,你应该打印 q
的值,而不是 &q
;在 main()
函数中,出于同样的原因,你也应该打印 qnap
的值,而不是 &qnap
。
这里有一个例子,可能会更清楚一些:https://play.golang.org/p/pDpL0-GYuM
英文:
&
gives you the address of a variable. &q
in your Logout
function gives you the address of q
, which is a local variable. The value of that local variable is, in turn, an address, because q
is itself a pointer (to a struct of type QNAP
). The memory address that's printed being different is a red herring; your nil pointer dereference is the real issue. If you want the same address, you would print the value of q
, not &q
; and in main()
you would likewise print the value of qnap
, not &qnap
, for the same reason.
Here's an example that might make things clearer: https://play.golang.org/p/pDpL0-GYuM
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论