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?

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



            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

            Category:Tremithousa Media in category "Tremithousa"Navigation menuUpload media34° 49′ 02.7″ N, 32° 26′ 37.32″ EOpenStreetMapGoogle EarthProximityramaReasonatorScholiaStatisticsWikiShootMe