Why does Box need 16 bytes in memory, but a referenced slice needs only 8? (on x64 machine) Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30 pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Why does Rust borrow checker reject this code?How do I implement a struct that takes a generic vector with lifetime annotations?Clone not invoked for Moved value?Which library to use for Weak referencesClosing stdout or stdinWhat is the use of into_boxed_slice() methods?Reverse order of a reference to immutable array sliceHow to prepend a slice to a VecWhy does storing to and loading from an AVX2 256bit vector have different results in debug and release mode?Why does a function taking a reference to a generic care that the generic is Sized?

Multi tool use
Multi tool use

Co-worker works way more than he should

Is there an efficient way for synchronising audio events real-time with LEDs using an MCU?

What is /etc/mtab in Linux?

Processing ADC conversion result: DMA vs Processor Registers

Is there a verb for listening stealthily?

Why isn't everyone flabbergasted about Bran's "gift"?

Simulate round-robin tournament draw

What to do with someone that cheated their way though university and a PhD program?

What is a 'Key' in computer science?

/bin/ls sorts differently than just ls

Is it OK if I do not take the receipt in Germany?

Why did Israel vote against lifting the American embargo on Cuba?

All ASCII characters with a given bit count

How would you suggest I follow up with coworkers about our deadline that's today?

Variable does not exist: sObjectType (Task.sObjectType)

What is the numbering system used for the DSN dishes?

Is it accepted to use working hours to read general interest books?

Writing a T-SQL stored procedure to receive 4 numbers and insert them into a table

When does Bran Stark remember Jamie pushing him?

Coin Game with infinite paradox

Is Bran literally the world's memory?

Protagonist's race is hidden - should I reveal it?

Determinant of a matrix with 2 equal rows

How to keep bees out of canned beverages?



Why does Box need 16 bytes in memory, but a referenced slice needs only 8? (on x64 machine)



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30 pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Why does Rust borrow checker reject this code?How do I implement a struct that takes a generic vector with lifetime annotations?Clone not invoked for Moved value?Which library to use for Weak referencesClosing stdout or stdinWhat is the use of into_boxed_slice() methods?Reverse order of a reference to immutable array sliceHow to prepend a slice to a VecWhy does storing to and loading from an AVX2 256bit vector have different results in debug and release mode?Why does a function taking a reference to a generic care that the generic is Sized?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








11















Consider:



fn main() 
// Prints 8, 8, 16
println!(
", , ",
std::mem::size_of::<Box<i8>>(),
std::mem::size_of::<Box<&[i8]>>(),
std::mem::size_of::<Box<[i8]>>(),
);



Why do owned slices take 16 bytes, but referenced slices take only 8?









share
























  • Playground: play.rust-lang.org/…

    – French Boiethios
    9 hours ago






  • 2





    Previous discussion: i.stack.imgur.com/Xt6L3.png

    – hellow
    8 hours ago

















11















Consider:



fn main() 
// Prints 8, 8, 16
println!(
", , ",
std::mem::size_of::<Box<i8>>(),
std::mem::size_of::<Box<&[i8]>>(),
std::mem::size_of::<Box<[i8]>>(),
);



Why do owned slices take 16 bytes, but referenced slices take only 8?









share
























  • Playground: play.rust-lang.org/…

    – French Boiethios
    9 hours ago






  • 2





    Previous discussion: i.stack.imgur.com/Xt6L3.png

    – hellow
    8 hours ago













11












11








11








Consider:



fn main() 
// Prints 8, 8, 16
println!(
", , ",
std::mem::size_of::<Box<i8>>(),
std::mem::size_of::<Box<&[i8]>>(),
std::mem::size_of::<Box<[i8]>>(),
);



Why do owned slices take 16 bytes, but referenced slices take only 8?









share
















Consider:



fn main() 
// Prints 8, 8, 16
println!(
", , ",
std::mem::size_of::<Box<i8>>(),
std::mem::size_of::<Box<&[i8]>>(),
std::mem::size_of::<Box<[i8]>>(),
);



Why do owned slices take 16 bytes, but referenced slices take only 8?







rust





share














share












share



share








edited 2 hours ago









Tim Diekmann

3,58291940




3,58291940










asked 9 hours ago









aminamin

1,29312042




1,29312042












  • Playground: play.rust-lang.org/…

    – French Boiethios
    9 hours ago






  • 2





    Previous discussion: i.stack.imgur.com/Xt6L3.png

    – hellow
    8 hours ago

















  • Playground: play.rust-lang.org/…

    – French Boiethios
    9 hours ago






  • 2





    Previous discussion: i.stack.imgur.com/Xt6L3.png

    – hellow
    8 hours ago
















Playground: play.rust-lang.org/…

– French Boiethios
9 hours ago





Playground: play.rust-lang.org/…

– French Boiethios
9 hours ago




2




2





Previous discussion: i.stack.imgur.com/Xt6L3.png

– hellow
8 hours ago





Previous discussion: i.stack.imgur.com/Xt6L3.png

– hellow
8 hours ago












2 Answers
2






active

oldest

votes


















14














Box<T> is basically *const T (Actually it's a newtype around Unique<T>, which itself is a NonNull<T> with PhantomData<T> (for dropck), but let's stick to *const T for simplicity).



A pointer in Rust normally has the same size as size_of::<usize>() except when T is a dynamically sized type (DST). Currently, a Box<DST> is 2 * size_of::<usize>() in size (the exact representation is not stable at the time of writing). A pointer to a DST is called FatPtr.



Currently, there are two kinds of DSTs: Slices and traits. A FatPtr to a slice is defined like this:



#[repr(C)]
struct FatPtr<T>
data: *const T,
len: usize,



Note: For a trait pointer, len is replaced by a pointer to the vtable.



With those information, your question can be answered:




  • Box<i8>: i8 is a sized type => basically the same as *const i8 => 8 bytes in size (with 64 bit pointer width)


  • Box<[i8]>: [i8] is a DST => basically the same as FatPtr<i8> => 16 bytes in size (with 64 bit pointer width)


  • Box<&[i8]>: &[i8] is not a DST. It's basically the same as *const FatPtr<i8> => 8 bytes in size (with 64 bit pointer width)




share
































    2














    The size of a reference depends on the "sizeness" of the referenced type:



    • A reference to a sized type is a single pointer to the memory address.


    • A reference to an unsized type is a pointer to the memory and the size of the pointed datum. That's what is called a fat pointer:



      #[repr(C)]
      struct FatPtr<T>
      data: *const T,
      len: usize,



    A Box is a special kind of pointer that points to the heap, but it is a pointer anyway.



    Knowing that, you understand that:




    • Box<i8> is 8 bytes because i8 is sized,


    • Box<&[i8]> is 8 bytes because a reference is sized,


    • Box<[i8]> is 8 bytes because a slice is unsized




    share























    • Box<[i8]> is 16 in your own playground link

      – Stargateur
      2 hours ago











    • @Stargateur I guess this was a typo :)

      – Tim Diekmann
      2 hours ago


















    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    14














    Box<T> is basically *const T (Actually it's a newtype around Unique<T>, which itself is a NonNull<T> with PhantomData<T> (for dropck), but let's stick to *const T for simplicity).



    A pointer in Rust normally has the same size as size_of::<usize>() except when T is a dynamically sized type (DST). Currently, a Box<DST> is 2 * size_of::<usize>() in size (the exact representation is not stable at the time of writing). A pointer to a DST is called FatPtr.



    Currently, there are two kinds of DSTs: Slices and traits. A FatPtr to a slice is defined like this:



    #[repr(C)]
    struct FatPtr<T>
    data: *const T,
    len: usize,



    Note: For a trait pointer, len is replaced by a pointer to the vtable.



    With those information, your question can be answered:




    • Box<i8>: i8 is a sized type => basically the same as *const i8 => 8 bytes in size (with 64 bit pointer width)


    • Box<[i8]>: [i8] is a DST => basically the same as FatPtr<i8> => 16 bytes in size (with 64 bit pointer width)


    • Box<&[i8]>: &[i8] is not a DST. It's basically the same as *const FatPtr<i8> => 8 bytes in size (with 64 bit pointer width)




    share





























      14














      Box<T> is basically *const T (Actually it's a newtype around Unique<T>, which itself is a NonNull<T> with PhantomData<T> (for dropck), but let's stick to *const T for simplicity).



      A pointer in Rust normally has the same size as size_of::<usize>() except when T is a dynamically sized type (DST). Currently, a Box<DST> is 2 * size_of::<usize>() in size (the exact representation is not stable at the time of writing). A pointer to a DST is called FatPtr.



      Currently, there are two kinds of DSTs: Slices and traits. A FatPtr to a slice is defined like this:



      #[repr(C)]
      struct FatPtr<T>
      data: *const T,
      len: usize,



      Note: For a trait pointer, len is replaced by a pointer to the vtable.



      With those information, your question can be answered:




      • Box<i8>: i8 is a sized type => basically the same as *const i8 => 8 bytes in size (with 64 bit pointer width)


      • Box<[i8]>: [i8] is a DST => basically the same as FatPtr<i8> => 16 bytes in size (with 64 bit pointer width)


      • Box<&[i8]>: &[i8] is not a DST. It's basically the same as *const FatPtr<i8> => 8 bytes in size (with 64 bit pointer width)




      share



























        14












        14








        14







        Box<T> is basically *const T (Actually it's a newtype around Unique<T>, which itself is a NonNull<T> with PhantomData<T> (for dropck), but let's stick to *const T for simplicity).



        A pointer in Rust normally has the same size as size_of::<usize>() except when T is a dynamically sized type (DST). Currently, a Box<DST> is 2 * size_of::<usize>() in size (the exact representation is not stable at the time of writing). A pointer to a DST is called FatPtr.



        Currently, there are two kinds of DSTs: Slices and traits. A FatPtr to a slice is defined like this:



        #[repr(C)]
        struct FatPtr<T>
        data: *const T,
        len: usize,



        Note: For a trait pointer, len is replaced by a pointer to the vtable.



        With those information, your question can be answered:




        • Box<i8>: i8 is a sized type => basically the same as *const i8 => 8 bytes in size (with 64 bit pointer width)


        • Box<[i8]>: [i8] is a DST => basically the same as FatPtr<i8> => 16 bytes in size (with 64 bit pointer width)


        • Box<&[i8]>: &[i8] is not a DST. It's basically the same as *const FatPtr<i8> => 8 bytes in size (with 64 bit pointer width)




        share















        Box<T> is basically *const T (Actually it's a newtype around Unique<T>, which itself is a NonNull<T> with PhantomData<T> (for dropck), but let's stick to *const T for simplicity).



        A pointer in Rust normally has the same size as size_of::<usize>() except when T is a dynamically sized type (DST). Currently, a Box<DST> is 2 * size_of::<usize>() in size (the exact representation is not stable at the time of writing). A pointer to a DST is called FatPtr.



        Currently, there are two kinds of DSTs: Slices and traits. A FatPtr to a slice is defined like this:



        #[repr(C)]
        struct FatPtr<T>
        data: *const T,
        len: usize,



        Note: For a trait pointer, len is replaced by a pointer to the vtable.



        With those information, your question can be answered:




        • Box<i8>: i8 is a sized type => basically the same as *const i8 => 8 bytes in size (with 64 bit pointer width)


        • Box<[i8]>: [i8] is a DST => basically the same as FatPtr<i8> => 16 bytes in size (with 64 bit pointer width)


        • Box<&[i8]>: &[i8] is not a DST. It's basically the same as *const FatPtr<i8> => 8 bytes in size (with 64 bit pointer width)





        share













        share


        share








        edited 27 mins ago

























        answered 8 hours ago









        Tim DiekmannTim Diekmann

        3,58291940




        3,58291940























            2














            The size of a reference depends on the "sizeness" of the referenced type:



            • A reference to a sized type is a single pointer to the memory address.


            • A reference to an unsized type is a pointer to the memory and the size of the pointed datum. That's what is called a fat pointer:



              #[repr(C)]
              struct FatPtr<T>
              data: *const T,
              len: usize,



            A Box is a special kind of pointer that points to the heap, but it is a pointer anyway.



            Knowing that, you understand that:




            • Box<i8> is 8 bytes because i8 is sized,


            • Box<&[i8]> is 8 bytes because a reference is sized,


            • Box<[i8]> is 8 bytes because a slice is unsized




            share























            • Box<[i8]> is 16 in your own playground link

              – Stargateur
              2 hours ago











            • @Stargateur I guess this was a typo :)

              – Tim Diekmann
              2 hours ago















            2














            The size of a reference depends on the "sizeness" of the referenced type:



            • A reference to a sized type is a single pointer to the memory address.


            • A reference to an unsized type is a pointer to the memory and the size of the pointed datum. That's what is called a fat pointer:



              #[repr(C)]
              struct FatPtr<T>
              data: *const T,
              len: usize,



            A Box is a special kind of pointer that points to the heap, but it is a pointer anyway.



            Knowing that, you understand that:




            • Box<i8> is 8 bytes because i8 is sized,


            • Box<&[i8]> is 8 bytes because a reference is sized,


            • Box<[i8]> is 8 bytes because a slice is unsized




            share























            • Box<[i8]> is 16 in your own playground link

              – Stargateur
              2 hours ago











            • @Stargateur I guess this was a typo :)

              – Tim Diekmann
              2 hours ago













            2












            2








            2







            The size of a reference depends on the "sizeness" of the referenced type:



            • A reference to a sized type is a single pointer to the memory address.


            • A reference to an unsized type is a pointer to the memory and the size of the pointed datum. That's what is called a fat pointer:



              #[repr(C)]
              struct FatPtr<T>
              data: *const T,
              len: usize,



            A Box is a special kind of pointer that points to the heap, but it is a pointer anyway.



            Knowing that, you understand that:




            • Box<i8> is 8 bytes because i8 is sized,


            • Box<&[i8]> is 8 bytes because a reference is sized,


            • Box<[i8]> is 8 bytes because a slice is unsized




            share













            The size of a reference depends on the "sizeness" of the referenced type:



            • A reference to a sized type is a single pointer to the memory address.


            • A reference to an unsized type is a pointer to the memory and the size of the pointed datum. That's what is called a fat pointer:



              #[repr(C)]
              struct FatPtr<T>
              data: *const T,
              len: usize,



            A Box is a special kind of pointer that points to the heap, but it is a pointer anyway.



            Knowing that, you understand that:




            • Box<i8> is 8 bytes because i8 is sized,


            • Box<&[i8]> is 8 bytes because a reference is sized,


            • Box<[i8]> is 8 bytes because a slice is unsized





            share











            share


            share










            answered 8 hours ago









            French BoiethiosFrench Boiethios

            11.4k44081




            11.4k44081












            • Box<[i8]> is 16 in your own playground link

              – Stargateur
              2 hours ago











            • @Stargateur I guess this was a typo :)

              – Tim Diekmann
              2 hours ago

















            • Box<[i8]> is 16 in your own playground link

              – Stargateur
              2 hours ago











            • @Stargateur I guess this was a typo :)

              – Tim Diekmann
              2 hours ago
















            Box<[i8]> is 16 in your own playground link

            – Stargateur
            2 hours ago





            Box<[i8]> is 16 in your own playground link

            – Stargateur
            2 hours ago













            @Stargateur I guess this was a typo :)

            – Tim Diekmann
            2 hours ago





            @Stargateur I guess this was a typo :)

            – Tim Diekmann
            2 hours ago



            jNfCxtANpXHXkI GDSc,tr8SfLk qY0hCz18qJP
            h,mCNgmw2u7qepc,aHsrMUDZPUGL4QtF

            Popular posts from this blog

            How to create a command for the “strange m” symbol in latex? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)How do you make your own symbol when Detexify fails?Writing bold small caps with mathpazo packageplus-minus symbol with parenthesis around the minus signGreek character in Beamer document titleHow to create dashed right arrow over symbol?Currency symbol: Turkish LiraDouble prec as a single symbol?Plus Sign Too Big; How to Call adfbullet?Is there a TeX macro for three-legged pi?How do I get my integral-like symbol to align like the integral?How to selectively substitute a letter with another symbol representing the same letterHow do I generate a less than symbol and vertical bar that are the same height?

            Българска екзархия Съдържание История | Български екзарси | Вижте също | Външни препратки | Литература | Бележки | НавигацияУстав за управлението на българската екзархия. Цариград, 1870Слово на Ловешкия митрополит Иларион при откриването на Българския народен събор в Цариград на 23. II. 1870 г.Българската правда и гръцката кривда. От С. М. (= Софийски Мелетий). Цариград, 1872Предстоятели на Българската екзархияПодмененият ВеликденИнформационна агенция „Фокус“Димитър Ризов. Българите в техните исторически, етнографически и политически граници (Атлас съдържащ 40 карти). Berlin, Königliche Hoflithographie, Hof-Buch- und -Steindruckerei Wilhelm Greve, 1917Report of the International Commission to Inquire into the Causes and Conduct of the Balkan Wars

            “Whose” combined with “all”, “every” etc Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Proper way to handle plurals with “whose”Is a sentence always grammatically incorrect if it has no verb?What’s wrong with “… enforce that …”“Every” being used instead of “ever”?“We're all each other has”Everyone vs every one vs allRight way to use transition “above all”“Which” instead of “whose” for inanimate objectsCan the relative pronoun “whose” be replaced by “of whom/which” in relative clauses?'all the following are' OR 'the following are all'