草庐IT

pointers - 在将 `slice` 附加到之后指向 `slice` 元素的指针的行为

coder 2023-07-01 原文

我想知道在附加 slice 之后指向 slice 元素的指针的行为是什么,例如:

package main

import "fmt"

func main() {
    my_slice := []int {3}

    silly_ptr := &my_slice[0]
    // Do we know that silly_ptr points to value equal 3
    // all the time? (If we don't explicitly change it).

    fmt.Printf("%p\n", silly_ptr)
    fmt.Println(*silly_ptr)

    for i := 0; i < 10; i++ {
        my_slice = append(my_slice, i)
    }

    silly_ptr_2 := &my_slice[0]

    fmt.Printf("%p\n", silly_ptr_2)
    fmt.Println(*silly_ptr_2)
}

产生:(没有惊喜)

0xc20800a200
3
0xc20805a000
3

我知道追加到动态数组时,在某些时候我们会重新填充整个数组,因此原始数组元素的内存地址不可靠。据我所知,类似的代码在 c++ 中有效,但 silly_ptr 可能指向任何东西。 rust 不允许对借用的 vector 进行变异,因此上述逻辑无法编译。

但是 Go 呢?我知道通过escape analysis 返回一个指向局部变量的指针是有效的,该变量只是为你在堆上创建的。我的直觉告诉我,同样的逻辑适用于上述情况。 silly_ptr 指向的内存位置不会被重新填充,因此将始终存储 3(如果我们不显式更改它)。这样对吗?

最佳答案

不,它不会总是存储 3。

Go 有内存管理。只要 slice 有一个指向底层数组的事件指针,底层数组就会被固定,就不会被垃圾回收。如果您有指向底层数组元素的指针,则可以更改该元素的值。例如,

package main

import (
    "fmt"
)

func pin() *int {
    s := []int{3}
    fmt.Println(&s[0])
    a := &s[0]
    s = append(s, 7)
    fmt.Println(&s[0])
    return a
}

func main() {
    a := pin()
    fmt.Println(a, *a)
    *a = 42
    fmt.Println(a, *a)
}

输出:

0xc82000a340
0xc82000a360
0xc82000a340 3
0xc82000a340 42

slice 描述符包含指向底层数组的指针,因此您可以看到与 slice 类似的内容。例如,

package main

import (
    "fmt"
)

func pin() []int {
    s := []int{3}
    fmt.Println(&s[0])
    d := s
    s = append(s, 7)
    fmt.Println(&s[0])
    return d
}

func main() {
    d := pin()
    fmt.Println(&d[0], d)
    d[0] = 42
    fmt.Println(&d[0], d)
}

输出:

0xc82000a340
0xc82000a360
0xc82000a340 [3]
0xc82000a340 [42]

关于pointers - 在将 `slice` 附加到之后指向 `slice` 元素的指针的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31633330/

有关pointers - 在将 `slice` 附加到之后指向 `slice` 元素的指针的行为的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  3. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  4. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  5. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  6. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  7. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  8. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  9. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  10. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

随机推荐