使用`as_ptr()`时如何阻止内存泄漏? [英] How to stop memory leaks when using `as_ptr()`?

查看:34
本文介绍了使用`as_ptr()`时如何阻止内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Since it's my first time learning systems programming, I'm having a hard time wrapping my head around the rules. Now, I got confused about memory leaks. Let's consider an example. Say, Rust is throwing a pointer (to a string) which Python is gonna catch.

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

In Rust, (I'm just sending the pointer of the CString)

use std::ffi::CString;

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

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

In Python, (I'm dereferencing the pointer)

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 时我应该如何释放它?

Now, my question is about freeing the memory. I thought it should be freed in Python, but then ownership pops in. Because, as_ptr seems to take an immutable reference. So, I got confused about whether I should free the memory in Rust or Python (or both?). If it's gonna be Rust, then how should I go about freeing it when the control flow has landed back into Python?

推荐答案

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

Your Rust function do_something constructs a temporary CString, takes a pointer into it, and then drops the CString. The *const c_char is invalid from the instant you return it. If you're on nightly, you probably want CString#into_ptr instead of CString#as_ptr, as the former consumes the CString without deallocating the memory. On stable, you can mem::forget the CString. Then you can worry about who is supposed to free it.

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

Freeing from Python will be tricky or impossible, since Rust may use a different allocator. The best approach would be to expose a Rust function that takes a c_char pointer, constructs a CString for that pointer (rather than copying the data into a new allocation), and drops it. Unfortunately the middle part (creating the CString) seems impossible on stable for now: CString::from_ptr is unstable.

一种解决方法是将(指向)整个CString 传递给 Python,并提供一个访问器函数来从中获取字符指针.您只需要将 CString 装箱并将该框转换为原始指针.然后你可以有另一个函数将指针转换回一个盒子并让它下降.

A workaround would to pass (a pointer to) the entire CString to Python and provide an accessor function to get the char pointer from it. You simply need to box the CString and transmute the box to a raw pointer. Then you can have another function that transmutes the pointer back to a box and lets it drop.

这篇关于使用`as_ptr()`时如何阻止内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆