我试图理解和学习cgo,作为其一部分,我编写了一个函数,使用C.stat检查文件权限。

import (
    "fmt"
    "unsafe"
    "os"
)
//#include <sys/stat.h>
//#include <stdlib.h>
import "C"

func CheckPerm(filename string) {

    statt := C.stat //stat struct from C
    path := C.CString(filename)
    st := *(*C.struct_stat)(unsafe.Pointer(statt)) //Casting unsafe pointer to C.struct_stat
    defer C.free(unsafe.Pointer(path)) //free
    defer C.free(unsafe.Pointer(statt))
    C.stat(path, &st)
    if st.st_mode & C.S_IRGRP > 0 || st.st_mode & C.S_IWGRP > 0 || st.st_mode & C.S_IXGRP > 0 || st.st_mode & C.S_IROTH > 0 || st.st_mode & C.S_IWOTH > 0 || st.st_mode & C.S_IXOTH > 0 {
        fmt.Println("file permission too broad, make it non-readable to groups and others.")
        os.Exit(1)
    }
    fmt.Println("File permission looks fine")

}

在将文件路径传递给函数时,它会错误地指出
*** Error in `/tmp/Build go-sync.go and run77go': double free or corruption (out): 0x0000000000609480 ***
SIGABRT: abort
PC=0x7fe4302f3267 m=0
signal arrived during cgo execution

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x401930, 0xc820097808, 0xc800000000)
/usr/lib/go/src/runtime/cgocall.go:120 +0x11b fp=0xc8200977d8 sp=0xc8200977a8
gosyncmodules._Cfunc_free(0x609480)
==========snip============

由于此处粘贴的最后一行gosyncmodules._Cfunc_free(0x609480),我删除了defer C.free(unsafe.Pointer(statt)),现在可以正常使用了。
  • 当我尝试释放所创建的结构时,为什么它会引发错误,而可以用来释放路径变量?
  • 如果不是这种情况,是否会导致类似的情况导致内存泄漏?
  • 最佳答案

    https://golang.org/cmd/cgo/#hdr-Go_references_to_C:

    // Go string to C string
    // The C string is allocated in the C heap using malloc.
    // It is the caller's responsibility to arrange for it to be
    // freed, such as by calling C.free (be sure to include stdlib.h
    // if C.free is needed).
    func C.CString(string) *C.char
    

    你的
    path := C.CString(filename)
    

    进行复制,而statt是普通的Go内存管理变量,则必须释放它。

    关于c - 在cgo,golang中使用free时获得双倍的免费或腐败(淘汰),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35455702/

    10-11 10:54