Cgo:Go分配的非结构体切片内存由C写入是否安全?
Go切片转C指针后严格控制写入长度是否安全?
场景代码
Go侧实现
a := []byte{0,1,2,3,4,5,6,7} C.some_method((*C.char)(unsafe.Pointer(&a[0])), C.int(len(a)))
C侧实现
void some_method(char* a, int a_len) { for (int i=0; i<a_len; i++) { a[i] = i+1; } }
结论
在严格控制写入长度的前提下,这种操作是安全的,但要满足几个核心前提:
- 写入的索引必须不超过原Go切片的容量(
cap(a)),更准确地说,不能超出len(a)-1(因为你传递的长度是len(a)),这样不会越界访问底层数组的内存,避免破坏Go的内存安全。 - 确保在C代码执行期间,该Go切片(或其底层数组的引用)处于Go的作用域内,不会被垃圾回收器回收或移动——只要切片还在当前Go代码的有效引用中,底层数组的地址就不会失效。
- 由于
byte和char在绝大多数平台上都是1字节的类型,这种类型转换不存在字节长度不匹配的问题,数据读写的字节对齐是兼容的。
简单说,只要C代码严格按照传递的a_len(或不超过切片容量)写入,同时保证切片在C操作期间不被GC处理,就不会有安全问题。
内容的提问来源于stack exchange,提问作者Wilson Luniz
相关产品推荐
相关产品推荐

