I have used Rust for some part of my project and created cdylib , but the problem is Rust memory management system deallocates the memory which must not be . so how do i prevent Rust from doing that?
i get the data as *mut u8 from C side and create Vec from that memory without allocating new memory , so now i have to prevent Vec to deallocate the memory
tested :
box::leak not working
std::mem::manuallydrop not working too
Vec deallocates its buffer when it goes out of scope. If you don't want it deallocated, don't create a Vec. Instead, use (for instance) std::slice::from_raw_parts to make a slice reference, which does not own its memory and won't try to deallocate it.
(Worth pointing out - calling Vec::from_raw_parts on a pointer that wasn't created from a Vec in the first place is already UB.)
but the problem is the prev code which is written before uses Vec , so i have only two options here looking in all of the code base and change all of it from Vec to slice which will break entire project !
other choice is to allocate memory for vec , copy everything from that slice to vec and then after processing copy back everything to that slice . i dont want to allocate too much mem so i went for straight creating a vec so im seeking for a way to prevent a vec from doing that
It may break less than you think. Vec can auto-deref to […], and so most call sites that pass a vector will still work unchanged if the argument type is changed to a slice.
If the existing code uses Vec, and does stuff that needs to use a Vec and not a slice (to grow/shrink/otherwise touch the allocation) then that is exactly why you cannot pass your unsized char * from C.
Your options are indeed either to make a copy or to change the code so that it does not use Vec.
no the code base does not use shrink and etc like that so using vec instead of slice could be valid choice , if i could prevent vec from deallocating the memory
If we forget for a moment than calling Vec::from_raw_parts on a C pointer is UB, isn't std::mem::forget enough to avoid the drop on the Vec and prevent the memory to be deallocated?
@SkillfulElectro Btw, UB means Undefined Behavior: to put it simple from that point on your program can do completely random things, even in places unrelated from where you constructed the vector. Using a slice is the better choice here.
From the small piece of code you showed us I guess you can have multiple problems. For example data is clearly a Rust object that gets dropped at the end of the function. We don't know what data is, but depending on how it is built even this alone can result in a double free when returning to C.
Anyway, ifdata is OK to be dropped and the problem is only in information.data you can use ManuallyDrop:
let not_dropped = ManuallyDrop::new(unsafe {data.data_as_vec().expect("NULL DATA")});
let mut information = info {
row : data.row ,
column : data.column ,
data : not_dropped,
};
smth!(&mut information);
Only if they are passing the vector by reference everywhere, and not calling any functions like push that touch the capacity - in other words, yes, but only when the way they use the Vec is limited to the functionality of a &(mut)[T]. Because if you pass a &mut Vec<T> to a function, the function can reallocate it internally and then you'd be forgetting the wrong thing (and too late).
smth!(&mut information) is suspicious, for instance.