I am using cbindgen to generate C bindings for a small Rust crate that implements the ULID specification. To avoid leaking information, I am generating an opaque struct ulid_ctx and returning a pointer to that context object when it is first created. I'm struggling a little bit with reconciling Rust's ownership semantics and C's laissez-faire approach to memory.
#[allow(non_camel_case_types)]
pub struct ulid_ctx {
seed: u32,
}
#[no_mangle]
pub extern "C" fn ulid_create(seed: u32) -> *mut ulid_ctx {
let ctx = ulid_ctx { seed: s };
Box::leak(Box::new(ctx))
}
#[no_mangle]
pub unsafe extern "C" fn ulid_ctx_destroy(ctx: *mut ulid_ctx) {
Box::from_raw(ctx);
}
Two questions:
- Does
Box::leak(Box::new(ctx))correctly allocate actxvalue on the heap and then inform Rust that the function no longer owns it? - Will
Box::from_raw(ctx);re-create a Box and then immediately drop it, thereby freeing the memory?
Although it's not a lot of data (32 bits), I would like to avoid creating a memory leak if possible.