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

Ever since I first studied system programming, it's not easy for me to wrap my head around rules. Now I'm confused about a memory leak. Consider an example. Let's say Rust casts a pointer (to a string) that Python will catch.

In Rust, (I just send a CString pointer)

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

In Python (I dereference a 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 

Now, my question is to free memory. I thought this should be freed in Python, but then ownership comes up. Because as_ptr seems to have an immutable link. So, I am confused about whether I should free memory in Rust or Python (or both?). If it is Rust, then how should I release it when the control flow returns to Python?

+7
python memory-leaks rust ctypes ffi
source share
1 answer

The Rust do_something function creates a temporary CString , takes a pointer into it, and then CString falls. *const c_char invalid from the moment it returns. If you spent the night, you most likely need CString#into_ptr instead of CString#as_ptr , since the former consumes CString without freeing up memory. At a stable level, you can mem::forget CString . Then you can worry about who should release him.

Getting rid of Python will be difficult or impossible, as Rust may use a different allocator. The best approach would be to expose a Rust function that takes a c_char pointer, c_char a CString for that pointer (rather than copying data to a new distribution) and omits it. Unfortunately, the middle part (creating CString ) seems stable at the moment unstable: CString::from_ptr unstable.

The workaround was to pass (a pointer) to the entire CString in Python and provide an access function to get a char pointer from it. You just need to insert the CString field and transform the window into a source pointer. Then you may have another function that converts the pointer back to a field and allows it to be discarded.

+7
source share

All Articles