dpcj32769 2016-02-19 14:18
浏览 665

CGO:如何使用malloc释放在C中分配的内存以避免内存泄漏

I am trying to use CGO to call an optimized C++ CPU-bound implementation of a complex algorithms from golang. Basically, it will pass a string into c++ function and get a string back. A simplified version of the code can be seen in the below:

//algo.go
package main

//#cgo LDFLAGS:
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//char* echo(char* s);
import "C"
import "unsafe"

func main() {
    cs := C.CString("Hello from stdio
")
    defer C.free(unsafe.Pointer(cs))
    var echoOut *C.char = C.echo(cs)
    //defer C.free(unsafe.Pointer(echoOut)); -> using this will crash the code
    fmt.Println(C.GoString(echoOut));
}


//algo.cpp
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>

using namespace std;

extern "C" {
    char* echo(char* o) {
        int len = sizeof(o) / sizeof(char);
        char* out = (char*)malloc(len * sizeof(char));
        strcpy(out, o);
        return out;
    }
}    

In this link, ppl mentions that C++ code should call "free" by itself to free the allocated memory: http://grokbase.com/t/gg/golang-nuts/149hxezftf/go-nuts-cgo-is-it-safe-to-malloc-and-free-in-seperate-c-functions. But then it's very tricky because my c++ function return an allocated pointer so that golang can get the result. I cannot call free in the c++ code? What should be the correct way to handle this? I have a webserver will call the c++ code per each request and want to make sure it doesn't introduce any memory leak.

Thanks.

  • 写回答

2条回答 默认 最新

  • doumu6997 2016-02-19 15:38
    关注

    Fix the memory allocation bug in your echo function. For example,

    algo.go:

    //algo.go
    package main
    
    //#cgo LDFLAGS:
    //#include <stdio.h>
    //#include <stdlib.h>
    //#include <string.h>
    //char* echo(char* s);
    import "C"
    import (
        "fmt"
        "unsafe"
    )
    
    func main() {
        cs := C.CString("Hello from stdio
    ")
        defer C.free(unsafe.Pointer(cs))
        var echoOut *C.char = C.echo(cs)
        defer C.free(unsafe.Pointer(echoOut))
        fmt.Println(C.GoString(echoOut))
    }
    

    algo.cpp:

    //algo.cpp
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    extern "C" {
        char* echo(char* o) {
            char* out = (char*)malloc(strlen(o)+1);
            strcpy(out, o);
            return out;
        }
    }
    

    Output:

    $ cd algo
    $ go build && ./algo
    Hello from stdio
    
    $ 
    
    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)