In C++
, we can use delete
without layout information. If I have used raw::TraitObject
to manually implement vtable
, how can I determine the layout of original one?
libc::free
doesn't look elegant.
I have solved the problem by putting a method in trait
to get the Layout
of real struct.
I believe malloc keeps track of this information for you, when you allocate memory it usually adds a bit of metadata to help keep track of the layout. They probably added the explicit Layout
requirement so they don't force particular design choices on implementors of Alloc
.
Would you be able to explain a little more about what you're trying to accomplish? You typically don't want to transmute a trait object to raw::TraitObject
because that erases all the type information, in particular things like the object's normal destructor (which would do the delete for you).
Layout
is used for alloc/dealloc because Rust uses sized deallocation - the allocator receives the size info explicitly.
For example, I want to realize Runtime Polymorphism
for any struct that implements Trait T
, and also want to manually control memory by operating raw pointer.
trait T {
fn test() {}
fn get_ori_layout(&self) -> Layout;
}
struct A {}
impl T for A {
fn get_ori_layout(&self) -> Layout {
Layout::from_size_align_unchecked(mem::size_of::<Self>(), mem::align_of::<Self>())
}
}
To dealloc memory, my solusion is like this, because the type of real struct can not be determined.
unsafe fn delete(trait_obj: raw::TraitObject) {
let obj = mem::transmute::<raw::TraitObject, &T>(trait_obj);
let layout = obj.get_ori_layout();
Global.dealloc(NonNull::new_unchecked(trait_obj.data).as_opaque(), layout);
}
But it doesn't look elegant.
You are right, alloc doesn't correspond to free.
You can use Layout::for_value(&trait_obj)
, rather than add a method to your trait.
Thanks!!!