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

查看:381
本文介绍了使用`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可能使用其他分配器.最好的方法是公开一个带c_char指针的Rust函数,为该指针构造一个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.

一种解决方法是将 entire CString 传递(指向)Python,并提供访问器函数以从中获取char指针.您只需将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天全站免登陆