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

标签 memory-management go memory-leaks malloc cgo

我正在尝试使用 CGO 从 golang 调用复杂算法的优化 C++ CPU 绑定(bind)实现。基本上,它将一个字符串传递给 C++ 函数并取回一个字符串。代码的简化版本如下所示:

算法.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\n")
    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));
}

算法.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;
    }
}    

在此链接中,ppl 提到 C++ 代码应自行调用“free”以释放分配的内存:http://grokbase.com/t/gg/golang-nuts/149hxezftf/go-nuts-cgo-is-it-safe-to-malloc-and-free-in-seperate-c-functions .但这非常棘手,因为我的 c++ 函数返回一个分配的指针,以便 golang 可以获得结果。我不能在 C++ 代码中调用 free 吗?处理这个问题的正确方法应该是什么?我有一个网络服务器会根据每个请求调用 C++ 代码,并希望确保它不会引入任何内存泄漏。

谢谢。

最佳答案

修复 echo 函数中的内存分配错误。例如,

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\n")
    defer C.free(unsafe.Pointer(cs))
    var echoOut *C.char = C.echo(cs)
    defer C.free(unsafe.Pointer(echoOut))
    fmt.Println(C.GoString(echoOut))
}

算法.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;
    }
}

输出:

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

$ 

关于memory-management - CGO:如何使用 malloc 从 go 中释放在 C 中分配的内存以避免内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35507467/

相关文章:

C# - 是否可以合并盒子?

go - 如何去 :generate stringer constants from multiple packages?

unit-testing - 无法在 golang : "unable to open database file [recovered]"-error 中打开 SQLite 数据库

go - 如何在 Golang 中使用 C++ 库?

java - 如何解决 swing 监听器内存泄漏?

c - Valgrind 内存泄漏可达

iphone - obj_msgSend 之后的 exc_bad_access with retainCount = 2

delphi - 为什么 Delphi 中的字符串内存过多?

带有 Jetty 的 Java 8 on linux 内存问题

python - 了解 Python 进程的内存增长(VmRSS 与 gc.get_objects)