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?

            The Calvary Singular or Plural The 2019 Stack Overflow Developer Survey Results Are InAre collective nouns always plural, or are certain ones singular?Is “audience” singular or plural?“Wasn't” vs. “weren't” in a vernacular sentence“My last couple of years” — singular or plural?Is 'rest' singular or plural?Is “all but one” singular or plural?Whether to use the singular or plural form of basis?Singular and Plural for numbersIs there a plural form of teeth?performance: plural vs singular?singular or plural nouns?Singular and Plural

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