使用 `as_ptr()` 时如何阻止内存泄漏?

How to stop memory leaks when using `as_ptr()`?

因为这是我第一次学习系统编程,所以我很难理解这些规则。现在,我对内存泄漏感到困惑。让我们考虑一个例子。比如说,Rust 正在抛出一个指针(指向一个字符串),Python 会捕获它。

在 Rust 中,(我只是发送 CString 的指针)

use std::ffi::CString;

pub extern fn do_something() -> *const c_char {
    CString::new(some_string).unwrap().as_ptr()
}

在 Python 中,(我取消引用指针)

def call_rust():
    lib = ctypes.cdll.LoadLibrary(rustLib)
    lib.do_something.restype = ctypes.c_void_p
    c_pointer = lib.do_something()
    some_string = ctypes.c_char_p(c_pointer).value

现在,我的问题是关于释放内存。我认为它应该在 Python 中被释放,但随后所有权突然出现。因为,as_ptr 似乎采用了不可变的引用。所以,我对我应该释放 Rust 中的内存还是 Python (或两者?) 感到困惑。如果它是 Rust,那么当控制流回到 Python 时,我应该如何释放它?

你的 Rust 函数 do_something 构造了一个临时的 CString,接受一个指向它的指针,然后 删除 CString*const c_char 从你 return 的那一刻起就无效了。如果你在夜间,你可能想要 CString#into_ptr 而不是 CString#as_ptr,因为前者在不释放内存的情况下消耗 CString。在稳定版中,您可以 mem::forget CString。然后你可以担心谁应该释放它。

从 Python 释放将是棘手的或不可能的,因为 Rust 可能使用不同的分配器。最好的方法是公开一个 Rust 函数,它接受一个 c_char 指针,为该指针构造一个 CString(而不是将数据复制到一个新的分配中),然后删除它。不幸的是,中间部分(创建 CString)目前似乎不可能稳定:CString::from_ptr 不稳定。

一种解决方法是将 整个 CString 传递(指向)到 Python 并提供访问函数以从中获取 char 指针.您只需要将 CString 框起来并将框转换为原始指针。然后你可以有另一个函数将指针变回一个盒子并让它掉落。