亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang 追加內存分配 VS. STL push_back 內存分配

Golang 追加內存分配 VS. STL push_back 內存分配

Go
大話西游666 2021-07-27 17:55:21
我比較了 Goappend函數和 STL vector.push_back,發現不同的內存分配策略讓我很困惑。代碼如下:// CPP STL codevoid getAlloc() {    vector<double> arr;    int s = 9999999;     int precap = arr.capacity();    for (int i=0; i<s; i++) {        if (precap < i) {            arr.push_back(rand() % 12580 * 1.0);            precap = arr.capacity();            printf("%d  %p\n", precap, &arr[0]);        } else {            arr.push_back(rand() % 12580 * 1.0);        }    }    printf("\n");    return;}// Golang code    func getAlloc() {    arr := []float64{}    size := 9999999    pre := cap(arr)    for i:=0; i<size; i++ {        if pre < i {            arr = append(arr, rand.NormFloat64())            pre = cap(arr)            log.Printf("%d %p\n", pre, &arr)        } else {            arr = append(arr, rand.NormFloat64())        }    }    return;}但是內存地址對于大小的增量是不變的,這讓我很困惑。順便說一句,這兩種實現(STL VS. Go)的內存分配策略不同,我的意思是擴展大小。有什么優點或缺點嗎?這是上面代碼的簡化輸出[大小和第一個元素地址]:Golang                            CPP STL2 0xc0800386c0                    2  004B19C04 0xc0800386c0                    4  004AE9B88 0xc0800386c0                    6  004B29E016 0xc0800386c0                   9  004B2A1832 0xc0800386c0                   13  004B2A6864 0xc0800386c0                   19  004B2AD8128 0xc0800386c0                  28  004B29E0256 0xc0800386c0                  42  004B2AC8512 0xc0800386c0                  63  004B2C201024 0xc0800386c0                 94  004B2E201280 0xc0800386c0                 141  004B31181600 0xc0800386c0                 211  004B29E02000 0xc0800386c0                 316  004B30802500 0xc0800386c0                 474  004B3A683125 0xc0800386c0                 711  004B5FD03906 0xc0800386c0                 1066  004B7610
查看完整描述

2 回答

?
達令說

TA貢獻1821條經驗 獲得超6個贊

你的 Go 和 C++ 代碼片段不是等價的。在 C++ 函數中,您正在打印向量中第一個元素的地址,而在 Go 示例中,您正在打印切片本身的地址。

與 C++ 一樣std::vector,Go 切片是一種小型數據類型,它包含一個指向包含數據的底層數組的指針。該數據結構在整個函數中具有相同的地址。如果你想在片中的第一元素的地址,你可以使用相同的語法與C ++: &arr[0]。


查看完整回答
反對 回復 2021-08-02
?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

您正在獲取指向切片標頭的指針,而不是實際的支持數組。您可以將切片標頭視為一個結構,例如


type SliceHeader struct {

    len,cap int

    backingArray unsafe.Pointer

}

當您追加并重新分配后備數組時,指針backingArray可能會更改(不一定,但可能)。但是,保存長度、上限和指向后備數組的指針的結構的位置不會改變——它仍然在你聲明它的堆棧上。嘗試打印&arr[0]而不是,&arr您應該會看到更接近您期望的行為。


std::vector順便說一下,這與 的行為幾乎相同。將切片視為vector比魔術動態數組更接近 a 。


查看完整回答
反對 回復 2021-08-02
  • 2 回答
  • 0 關注
  • 294 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號