【问题标题】:Why does the memory address change after slice assignment为什么切片分配后内存地址会改变
【发布时间】:2020-03-06 17:55:52
【问题描述】:

有两个问题我不明白。
第一种是一个slice变量赋值给另一个变量,发现新变量的地址和变量的地址不一致。我的理解是slice共享内存,按照原理,它们的地址是一样的。

第二个是slice变量容量不足时,append操作后内存地址不变。应该按原理改,因为内存不足时会重新分配内存地址。

我会很感激你的 cmets。

var a = []int{1,2,3}
fmt.Printf("%p\n",&a)
b:=a
fmt.Printf("%p\n",&b) 1)、the first question
b=append(b,0)
fmt.Printf("%p\n",&b) 2)、the second question
fmt.Println(a)
fmt.Println(b)

运行结果是:

0xc04204c3a0
0xc04204c3e0
0xc04204c3e0
[1 2 3]
[1 2 3 0]

【问题讨论】:

    标签: go


    【解决方案1】:

    切片值包含指向后备数组的指针、长度和容量。有关详细信息,请参阅Go Slices: usage and internals

    以下是对问题中代码的一些评论:

    var a = []int{1, 2, 3}
    
    // Print address of variable a
    fmt.Printf("%p\n", &a)
    
    b := a
    
    // Print address of variable b. The variable a and b
    // have different addresses.
    fmt.Printf("%p\n", &b)
    
    b = append(b, 0)
    
    // Print address of variable b. Append did not change
    // the address of the variable b.
    fmt.Printf("%p\n", &b)
    

    打印第一个切片元素的地址以获得您期望的结果。

    var a = []int{1, 2, 3}
    
    // Print address of a's first element
    fmt.Printf("%p\n", &a[0])
    
    b := a
    
    // Print address of b's first element. This prints
    // same value as previous because a and b share a backing
    // array.
    fmt.Printf("%p\n", &b[0])
    
    b = append(b, 0)
    
    // Print address of b's first element. This prints a 
    // different value from previous because append allocated
    // a new backing array.
    fmt.Printf("%p\n", &b[0])
    

    【讨论】:

    • 谢谢,我误以为结构体变量存放的是整个数据。
    【解决方案2】:
    // create a new slice struct which contains length, capacity and the underlying array. 
    // len(a)=3, cap(a)=3
    var a = []int{1,2,3}
    
    // `&a` means the pointer to slice struct
    fmt.Printf("%p\n",&a)
    
    // `b` is another newly created variable of slice struct, so `&b` differs from `&a`, 
    // but they share the same underlying array.
    // len(b)=3, cap(b)=3
    b := a
    
    // the underlying array of `b` has been extended, and been newly allocated.
    // but the pointer of `b` remains.
    // len(b)=4, cap(b)=6
    b = append(b, 0)
    

    希望这些cmets可以帮助到你

    【讨论】:

      猜你喜欢
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 2021-10-13
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多