I'm trying to call some Rust code from C and get a result back, but I'm getting a "pointer being freed was not allocated" error on the Rust side.
I want to call the hex::encode function. I pass in a pointer to some bytes, the length, and a pointer allocated in C with malloc. I want the result of the conversion passed back at this pointer.
The Rust function:
extern crate libc; use hex; use std::ffi::CString; use std::os::raw::c_char; use std::vec::Vec; use std::{ffi, ptr, slice}; #[no_mangle] pub extern "C" fn bytes_to_hex_string(bp: *mut u8, bp_size: usize, sp: *mut c_char) -> i8 { println!("1"); let p_vec = unsafe { Vec::from_raw_parts(bp, bp_size, bp_size + 1) }; println!("2"); let str = hex::encode(p_vec); println!("3"); let bytes = str.as_bytes(); println!("4"); let cs = CString::new(bytes).unwrap(); // will fail if bytes has "gap" (null) in sequence println!("5"); unsafe { libc::strcpy(sp, cs.as_ptr()); } println!("6"); return 1; } Called from this C code:
#include <string.h> #include <stdio.h> #include <stdlib.h> int8_t bytes_to_hex( uint8_t *, unsigned int, char *); int main() { char *ptr = "Hello World!"; char *hex = (char *)malloc(1000); printf("about to call....\n"); bytes_to_hex_string((uint8_t*)ptr,strlen(ptr),hex); printf("about to print....\n"); printf("%s\n",hex); printf("about to free....\n"); free(hex); } When I run the program:
$ ./a.out about to call.... 1 2 a.out(2941,0x7fffccae03c0) malloc: *** error for object 0x10afe2b80: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap: 6 It looks like the Rust code inside the hex crate is freeing the ptr pointer, is that right?
Is there a way round this somehow? I would prefer for the allocation and freeing to happen in C, but I am open to any suggestions to solve this!
Vec::from_raw_parts: "ptrneeds to have been previously allocated viaString/Vec<T>(at least, it's highly likely to be incorrect if it wasn't)." Generally, it is meant to be used as a way to recover aVecthat was previously disassembled/forgotten, not as a way to create vectors from an arbitrary memory buffer. As the answer suggests, turning these raw parts into a slice is most likely the right way to go.