Print value behind raw pointer without dropping

I've been fiddling with some FFI with a Ruby project and I'm curious if this is the idiomatic way of printing/interacting with a value behind a raw pointer without dropping it.

#[no_mangle]
pub extern "C" fn sql_debug_query(query: *mut Query) {
    let query = unsafe { Box::from_raw(query) };
    println!("{:?}", query);
    std::mem::forget(query); // this is required so the Box destructor isn't called, right?
}

I have a method to create a query that uses Box::into_raw(Box::new(query)), and a complementary method to free a query that just does unsafe { Box::from_raw(query); }. My question - is this (Box::from_raw / ... / std::mem::forget) the correct/community-accepted method of inspecting a value behind a raw pointer? Is there any more concise way to express this, something like query.box_borrow_raw that won't drop the Box when it goes out of scope? Should my fn accept *mut *mut Query instead?

Thanks for any advice!

You can just reborrow it:

let query = unsafe { &*query };
println!("{:?}", query);

Edit: that function should be marked unsafe though

4 Likes

To add to @SkiFire13 's answer:

  1. If your function can't free the memory that query points to, then it doesn't own that memory. So you want a reference, not an owned value like Box.
  2. Your function leads to undefined behavior if a null, unaligned, or dangling pointer is passed in. Because null pointers can be constructed in safe code, you need to mark your function as unsafe and document that it has a safety invariant that the compiler can't check.
2 Likes

It seems like users.rust-lang.org is a better fit for this thread (internals.rust-lang.org is for the development of Rust (the language) and associated tooling (e.g., the rustc compiler)).

7 Likes

Ah! I wondered why I couldn’t find any non-internal tags and why I had to register an account to post, didn’t even think to check the URL.

Thanks all for the help anyways, I’ll use the correct forum next time :upside_down_face:

1 Like