草庐IT

pointers - Go内存地址改变

coder 2024-07-07 原文

我很新,所以请耐心等待。我正在尝试通过 go 与我的 QNAP NAS 进行交互。到目前为止,我可以登录,但不能退出。好像qnap的内存地址变了:

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()

}

此代码打印以下内容:

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

最佳答案

& 给你一个变量的地址。 Logout 函数中的 &q 为您提供了 q 的地址,这是一个局部变量。该局部变量的 又是一个地址,因为q 本身就是一个指针(指向QNAP 类型的结构)。打印出来的不同内存地址是一个转移注意力的问题;您的零指针取消引用是真正的问题。如果你想要相同的地址,你会打印q的值,而不是&q;出于同样的原因,在 main() 中,您同样会打印 qnap 的值,而不是 &qnap

下面是一个可能会让事情更清楚的例子:https://play.golang.org/p/pDpL0-GYuM

关于pointers - Go内存地址改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44137001/

有关pointers - Go内存地址改变的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  3. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  4. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  5. ruby - 改变替换的大小写 - 2

    我有以下内容:text.gsub(/(lower)(upper)/,'\1\2')我可以将\2替换为大写吗?类似于:sed-e's/\(abc\)/\U\1/'这在Ruby中可行吗? 最佳答案 查看gsub文档:str.gsub(模式){|匹配|block}→new_str在block形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量将被适当设置。block返回的值将替换为每次调用的匹配项。"alowerupperb".gsub(/(lower)(upper)/){|s|$1+""+$2.upcase}

  6. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

  7. ruby-on-rails - 验证电子邮件地址是 Paypal 用户 - 2

    我想验证一个电子邮件地址是否是PayPal用户。是否有API调用来执行此操作?是否有执行此操作的ruby​​库?谢谢 最佳答案 GetVerifiedStatus来自PayPal'sAdaptiveAccounts平台会为您做这件事。PayPal没有任何codesamples或SDKs用于Ruby中的自适应帐户,但我确实找到了编写codeforGetVerifiedStatusinRuby的人.您需要更改该代码以检查他们拥有的帐户类型的唯一更改是更改if@xml['accountStatus']!=nilaccount_status

  8. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  9. ruby-on-rails - 从 Geocode 经纬度获取地址 - 2

    对于我的大部分应用程序,我从Geocoder获取城镇/城市的纬度、经度、邮政编码等。我只是投入城市和州,作为返回,我得到了我处于一个有field的场景中。该场所需要一个地址,我正在从另一个来源获取该场所的纬度和经度。使用Geocodergem,我可以通过给地址提供经纬度来获取地址吗? 最佳答案 在Rails控制台中运行。latitude=40.0397longitude=-76.30144geo_localization="#{latitude},#{longitude}"query=Geocoder.search(geo_loca

  10. ruby-on-rails - 内存中具有相同 ID 的更多对象? - 2

    在部署在heroku上的Rails应用程序(v:3.1)中,我在内存中获得了更多具有相同ID的对象。我的heroku控制台日志:>>Project.find_all_by_id(92).size=>2>>ActiveRecord::Base.connection.execute('select*fromprojectswhereid=92').to_a.size=>1这怎么可能?可能是什么问题? 最佳答案 解决方案根据您的SQL查询,您的数据库中显然没有重复条目。也许您的类项目中的size或length方法已被覆盖。我试过find_

随机推荐