Go内存地址更改

huangapple go评论114阅读模式
英文:

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

huangapple
  • 本文由 发表于 2017年5月23日 22:02:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/44137001.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定