Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向golang中的内存位置写入但不从中读取时,SIGSEGV_Go - Fatal编程技术网

向golang中的内存位置写入但不从中读取时,SIGSEGV

向golang中的内存位置写入但不从中读取时,SIGSEGV,go,Go,我的印象是,使用不安全的包可以读取/写入任意数据。我试图更改接口{}指向的值,而不更改指针本身 假设接口{}实现为 type _interface struct { type_info *typ value unsafe.Pointer } 虽然读取成功,但SIGSEGV设置失败 func data(i interface{}) unsafe.Pointer { return unsafe.Pointer((*((*[2]uintptr)(unsafe.Pointer(

我的印象是,使用
不安全的
包可以读取/写入任意数据。我试图更改
接口{}
指向的值,而不更改指针本身

假设
接口{}
实现为

type _interface struct {
    type_info *typ
    value unsafe.Pointer
}
虽然读取成功,但SIGSEGV设置失败

func data(i interface{}) unsafe.Pointer {
    return unsafe.Pointer((*((*[2]uintptr)(unsafe.Pointer(&i))))[1])
}

func main() {
    var i interface{}
    i = 2
    fmt.Printf("%v, %v\n", (*int)(data(i)), *(*int)(data(i)))
    *((*int)(data(i))) = 3
}

我做错了什么事,还是在golang不可能。。。下面是我目前如何理解您的第二个代码示例,以防我犯了错误(如果您注意到我所描述的内容有任何错误,我的答案可能是无可挽回的错误,您应该忽略我要说的其他内容)

  • main
    中的接口
    i
    分配内存
  • i
    的值设置为值为2的整数类型
  • 数据中的接口
    i
    分配内存
  • 将main的
    i
    值复制到data的
    i
    ;也就是说,将新接口的值设置为值为2的整数类型
  • 将新变量的地址强制转换为指向
    uintpttr
    的length-2数组的指针(使用
    unsafe.pointer
    作为强制编译器接受此强制转换的中介)
  • 将数组的第二个元素(其值是
    data
    i
    的值部分的地址)强制转换回
    不安全的.指针
    ,并返回它
  • 我已经在更多的步骤中做了同样的事情,但不幸的是我遇到了所有相同的问题:程序识别出我有一个非nil指针,并且它能够取消对指针的引用以进行读取,但使用相同的指针进行写入会产生运行时错误

    这是第六步,
    go vet
    抱怨,我认为这是因为,根据

    uintptr是整数,不是引用。将指针转换为uintptr将创建一个没有指针的整数值 语义学。即使uintptr持有某个对象的地址,垃圾收集器也不会在对象移动时更新该uintptr的值,该uintptr也不会阻止对象被回收

    更重要的是,据我所知(尽管我承认在不扫描编译器和运行时源代码的情况下挖掘显式确认时遇到了困难),运行时似乎不会跟踪
    接口{}
    类型的值部分,因为它是一个带有自己引用计数的离散指针;当然,您可以将
    接口{}
    中的两个字都压在整个过程中,但这似乎根本不是您想要做的事情(写入接口类型中指针的内存地址,而无需移动指针)

    有趣的是,我们似乎能够定义自己的结构化类型,而编译器没有对其进行特殊处理(接口显然有些特殊,带有类型断言语法等等)。也就是说,我们可以使用
    unsafe.Pointer
    来维护指向内存中特定点的引用,并且无论我们将其强制转换到什么位置,即使值发生变化,内存地址也不会移动(并且可以通过将其强制转换到其他位置来重新解释该值)。让我有点吃惊的是,至少在我自己的例子中,至少在操场环境中,所指向的值似乎没有固定的大小;我们可以建立一个要写入一次的地址,即使数据量很大(或很小),重复写入该地址也会成功

    当然,至少在这个实现中,我们失去了许多其他和接口类型相关联的东西,特别是非空接口类型(即方法)。所以,没有办法用它来(例如)制作一个超级鬼鬼祟祟的“泛型”类型。一个接口似乎是它自己的值,该值定义的一部分是内存中的地址,但它与指针并不完全相同