gpt4 book ai didi

go - 使用 calloc() 与 make() 进行 slice 时,程序会更改内存值

转载 作者:行者123 更新时间:2023-12-01 22:33:00 24 4
gpt4 key购买 nike

我正在尝试手动构建一个指针 slice ,并使用 C.calloc() 来分配 slice 的数组部分。我能够成功地做到这一点,尽管当我尝试添加我用 make() 分配的指针时,一些值(指针指向的)似乎随机改变。另一方面,如果我为要添加的指针使用 C.calloc() 空间,则值不会更改。或者,如果我使用 make() 分配 slice 并且我添加的指针使用 make() 分配,则值不会更改。

我确实注意到使用 C.calloc() 与 make() 时指针的内存位置非常不同,但我不明白为什么这会导致内存随机更改。我是 Go 新手,所以如果我忽略了一些非常简单的内容,请原谅我。

这是我用于手动分配 slice 的代码:

type caster struct {
ptr *byte;
len int64;
cap int64;
}

var temp caster;
temp.ptr=(*byte)(C.calloc(C.ulong(size),8));
temp.len=int64(size);
temp.cap=int64(size);
newTable.table=*(*[]*entry)(unsafe.Pointer(&temp));

如果我添加的条目分配如下:
var temp caster;
var e []entry;
temp.ptr=(*byte)(C.calloc(C.ulong(ninserts),8));
temp.len=int64(ninserts);
temp.cap=int64(ninserts);
e=*(*[]entry)(unsafe.Pointer(&temp));

for i:=0;i<ninserts;i++ {
e[i].val=hint64(rand.Int63());
}

for i:=0;i<ninserts;i++ {
ht.insert(&e[i]);
}

尽管如果按如下方式分配条目,则它们的内存会随机更改:
var e []entry = make([]entry, ninserts); 

for i:=0;i<ninserts;i++ {
e[i].val=hint64(rand.Int63());
}

for i:=0;i<ninserts;i++ {
ht.insert(&e[i]);
}

除非我按以下方式正常构建 slice :
newTable.table = make([]*entry,  size);

最佳答案

I am trying to build a slice of pointers manually and with C.calloc() for allocating the array portion of the slice.


这是明确禁止的。
引用 official cgo documentation :

Go is a garbage collected language, and the garbage collector needs to know the location of every pointer to Go memory. Because of this, there are restrictions on passing pointers between Go and C.

In this section the term Go pointer means a pointer to memory allocated by Go (such as by using the & operator or calling the predefined new function) and the term C pointer means a pointer to memory allocated by C (such as by a call to C.malloc). Whether a pointer is a Go pointer or a C pointer is a dynamic property determined by how the memory was allocated; it has nothing to do with the type of the pointer.

Note that values of some Go types, other than the type's zero value, always include Go pointers. This is true of string, slice, interface, channel, map, and function types. A pointer type may hold a Go pointer or a C pointer. Array and struct types may or may not include Go pointers, depending on the element types. All the discussion below about Go pointers applies not just to pointer types, but also to other types that include Go pointers.


上面的黑体字是我的。这意味着您不能通过 C 的分配器分配任何这些类型。

It is possible to defeat this enforcement by using the unsafe package, and of course there is nothing stopping the C code from doing anything it likes. However, programs that break these rules are likely to fail in unexpected and unpredictable ways.


您自己的这段代码:
newTable.table=*(*[]*entry)(unsafe.Pointer(&temp));

违反了规则,但破坏了它们的执行。您已经分配了 C 内存,现在正尝试以 slice 的形式将其用作 Go 内存。

关于go - 使用 calloc() 与 make() 进行 slice 时,程序会更改内存值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58686458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com