Is there a good way to read the memory content of the C pointer?

Hi, everyone.
I'm writing a C dynamic shared library using rust. I defined a function:

fn rsweb_cb(
    ctx: *mut SkynetContext,
    msg: *const c_void,
    sz: size_t,
) -> c_int {
    let msg_str = CString::from_raw(msg as *mut c_char).into_string().unwrap();
    println!("msg is {}", msg_str);
    0
}

The param msg in the function rsweb_cb is a pointer defined in C, and I want to read it's content in the rsweb_cb. But it will cause a crash:

skynet(17968,0x70000c847000) malloc: *** error for object 0x7ffc5640c8b0: pointer being freed was not allocated
skynet(17968,0x70000c847000) malloc: *** set a breakpoint in malloc_error_break to debug

Because the msg_str will destroy its memory while the function was executed. So I have to copy the memory content of msg pointer, and write like this:

fn rsweb_cb(
    ctx: *mut SkynetContext,
    msg: *const c_void,
    sz: size_t,
) -> c_int {
    let layout = Layout::array::<i8>(sz).unwrap();
    let msg_cpy = alloc_zeroed(layout);
    ptr::copy(msg, msg_cpy as *mut c_void, sz);
    let msg_str = CString::from_raw(msg_cpy as *mut c_char).into_string().unwrap();
    println!("msg is {}", msg_str);
    0
}

Then the program can run correctly.

In my opinions, I only want to read the content of the C pointer, not want to destroy it memory content, but make a copy may be a little inefficient. I don't know if there is a better way to read the content without copying it.

Don't use CString on something you don't want to destroy. You probably want CStr instead:

fn rsweb_cb(
    ctx: *mut SkynetContext,
    msg: *const c_void,
    sz: size_t,
) -> c_int {
    let msg_str = CStr::from_raw(msg as *mut c_char).to_str().unwrap().to_string();
    println!("msg is {}", msg_str);
    0
}

For completeness, any method named from_raw is probably intended only to undo a corresponding into_raw, and not to accept arbitrary pointers. You can verify this by looking at the relevant documentation, which is good practice anyway when calling an unsafe fn.

1 Like

Yeah, CStr::from_ptr() is a good solution.
Thanks.

Yeah, borrowing a string that was allocated by foreign code should use [ CStr ].

Thanks.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.