While trying to convert a [&str] or Vec<&str> to a list of C-String-pointers to be passed by FFI, I received some odd results. When I broke down the problem I came up with the following code:
let raw_ptr = &'@' as *const char as *const i8;
println!("Dereferenced: {}", unsafe { *raw_ptr });
println!("Dereferenced: {}", unsafe { *raw_ptr });
println!("Dereferenced: {}", unsafe { *raw_ptr });
println!("Dereferenced: {}", unsafe { *raw_ptr });
which correctly results in:
Dereferenced: 64
Dereferenced: 64
Dereferenced: 64
Dereferenced: 64
But running the following code:
let raw_ptr: *const i8 = std::ffi::CString::new("A").unwrap().as_ptr();
println!("Dereferenced: {}", unsafe { *raw_ptr });
println!("Dereferenced: {}", unsafe { *raw_ptr });
println!("Dereferenced: {}", unsafe { *raw_ptr });
println!("Dereferenced: {}", unsafe { *raw_ptr });
results in
Dereferenced: 65
Dereferenced: 40
Dereferenced: 40
Dereferenced: 40
The first line always outputs the correct result and each subsequent access seems to point somewhere wrong. The exact value depends on the programs history. I also tried to artificially expand the raw_ptr
's lifetime by re-using it at the end of the code, but to no avail.
One more test:
let raw_ptr: *const i8 = std::ffi::CString::new("A").unwrap().as_ptr();
unsafe {
println!("Dereferenced: {}", *raw_ptr);
println!("Dereferenced: {}", *raw_ptr);
println!("Dereferenced: {}", *raw_ptr);
println!("Dereferenced: {}", *raw_ptr);
}
results in
Dereferenced: -88
Dereferenced: -88
Dereferenced: -88
Dereferenced: -88
... which makes me think my approach is completely broken.
In the original code I tried to convert multiple strings using CString, but only some pointers came out as expected.
Can someone please explain to me, what's wrong with this code?