#How Box smart pointers works internally

84 messages · Page 1 of 1 (latest)

pliant drift
#

Just out of curiosity I wanna know how exactly it works internally cause it uses the attribute macro #[rustc_box] but no idea how it works internally like can I create my own box by using this same attribute macro #[rustc_box] .??

short compass
#

Where do you see rustc_box? Box has some special behavior like that dereferencing can consume the box. This is done with the #[lang = "owned_box"] attribute (this is a bulit-in attribute, not a macro, and only allowed in the standard library). But for the most part it's just a pointer that allocates in its constructor and deallocates in its drop. There might be some optimizations that only Box can do, and it has some special API rules (see https://doc.rust-lang.org/reference/special-types-and-traits.html#boxt), but other than that you can create your own box that does the same thing.

frank wraith
#

#[rustc_box] basically replaces the following expression with a call to alloc, but with some optimizations

clever path
#

(I haven't bothered to make it deallocate everything properly if Drop panics though. I'm too lazy for that lol)

#

(Also, it's untested.)

#

It's an intrinsic in order to prevent Box::new on large arrays from copying stuff around too much, especially in debug mode.

pliant drift
#
pub fn into_inner(self) -> T {
        unsafe {
            let this = ManuallyDrop::new(self);
            let value = this.0.read();
            let layout = Layout::new::<T>();
            if layout.size() != 0 {
                dealloc(this.0.as_ptr().cast(), layout);
            }
            value
        }
    }
``` in this code your are dropping the struct itself and the pointer and then  returning the value
#

This

clever path
clever path
#

For my type, you have to call into_inner.

pliant drift
#

Oh i see

clever path
#

I cannot make my type work like Box in this way.

pliant drift
#

Got it

pliant drift
pliant drift
clever path
clever path
pliant drift
#
pub fn into_inner(self) -> T {
        unsafe {
            let this = ManuallyDrop::new(self);
            let value = this.0.read();
            let layout = Layout::new::<T>();
            if layout.size() != 0 {
                dealloc(this.0.as_ptr().cast(), layout);
            }
            value
        }
    }
``` in this code your are dropping the struct  and the pointer and then  returning the value
#

Am I correct.??

clever path
pliant drift
#

Also why with self

clever path
pliant drift
#

By this function

#

So what's the need to Use ManualDrop

clever path
pliant drift
clever path
pliant drift
#

But what's the need of that

#

In this case

#

.??

clever path
#

Because I want to disable the drop thing

pliant drift
clever path
#

Because I already moved away the T. If self is dropped again, the Drop impl will call drop_in_place on the T

pliant drift
#

self is been moved now you can't do anything with MyBox.??

#

Again

clever path
#

When is it moved?

pliant drift
#

I hope this makes some sence if I am not wrong

clever path
pliant drift
#

Actually I am noob I know something new is going to come I am ready for that

clever path
pliant drift
#

Sorry

#

I mean into_inner()

pliant drift
clever path
#

What does this screenshot mean?

pliant drift
#

For that too

#

I mean

#

If we

#

Are dropping the self what's the disadvantage in that..?

#

Also it's been moved

clever path
pliant drift
clever path
#

Inside the Drop impl, we call drop_in_place.

#

Oh ok lol

pliant drift
#

I mean it will drop the value twice

#

😭😭😭 am I right

#

That actually makes sence now

pliant drift
#

And sorry

frigid flame
#

I guess if you don't prevent dropping you basically double free since into_inner already frees the allocation

pliant drift
# clever path Inside the Drop impl, we call drop_in_place.

Sorry what if we just remove from into_inner rs if layout.size() != 0 { dealloc(this.0.as_ptr().cast(), layout); } then I guess there is no need to use ManualDrop cause as the value goes out of scope drop will be called and the value will be freed up

clever path
pliant drift
pliant drift
clever path
clever path
pliant drift