go cgo gc


原文链接: go cgo gc

cgo调用内存泄露:C.GostringN()生成的string不会被GC?

package main

/*
#include <stdlib.h>
#include <malloc.h>
void mal(char **p) {
int l = 1000000;
*p= (char *)malloc(l);
*(*p+l-2) = 'a';
*(*p+l-1) = 'b';
}
*/
import "C"
import (
"fmt"
"sync"
"time"
"unsafe"
)

func main() {
    time.Sleep(time.Second * 10)
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            var p *C.char
            C.mal(&p)
            defer C.free(unsafe.Pointer(p))
            l := 1000000
            ss := C.GoStringN(p, C.int(l)) // ss不会被GC
            if string(ss[l-2:]) != "ab" {
                fmt.Println("not ab")
            }
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println("complete!")
    time.Sleep(time.Second * 300)
}

注意:
GoStringN是拷贝缓冲区生成新对象。https://golang.org/cmd/cgo/#hdr-Go_references_to_CA few special functions convert between Go and C types by making copies of the data. 不是GoStringN结果没被GC,是C里malloc出来的东西需要自己手工free掉。

`