Why does "Heap.dealloc" need "Layout"?


#1

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.


#2

I have solved the problem by putting a method in trait to get the Layout of real struct.


#3

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).


#4

Layout is used for alloc/dealloc because Rust uses sized deallocation - the allocator receives the size info explicitly.


#5

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.


#6

You are right, alloc doesn’t correspond to free.


#7

You can use Layout::for_value(&trait_obj), rather than add a method to your trait.


#8

Thanks!!!