Memory Size Confusion

Hi guys, I am learning Rust and currently looking for the std::mem::size_of etc topics. Here is my code:

let empty_vec_size = std::mem::size_of::<Vec<(i32, String)>>();
    
    let some_vec = vec![(123, String::from("some string")), (1, String::from("another string"))];
    
    let vec_values_size = std::mem::size_of_val(&some_vec);
    
    let first_item = (123, String::from("some string"));
    let second_item = (1, String::from("another string"));
    
    let first_item_size = std::mem::size_of_val(&first_item);
    let second_item_size = std::mem::size_of_val(&second_item);
    
    let total_size = first_item_size + second_item_size;
    
    println!("empty vec size: {}\n vec with values size: {}\n total_size: {}", empty_vec_size, vec_values_size, total_size);

When I run this code, the output gives:

empty vec size: 24
 vec with values size: 24
 total_size: 64

What is going on here? Why empty vec size and vec with values have same sizes? Any help will be appreciated. Thanks!

Update: updated vec size to empty vec size

The mem::size_of function measures a very specific thing, which is the size that a variable of that type would take up on the stack; or the offset (in memory, in bytes) between subsequent elements of the type in an array/vector.

This notion of “size” ignores anything behind any nonzero level of indirection. It is not meant for any informative purpose on overall RAM usage associated with some data, instead mem::size_of serves very simple technical purposes: one example would be implementing the low-level implementation details of a vector-like type, where you’d need to calculate the correct offset in bytes for the Nth element.

If you are interested in some more “informative function returning overall RAM usage associated with some data”, take a look at crates like get-size or deepsize.

3 Likes

size_of() returns the size of the very type you give it. A Vec doesn't store its elements inline, it heap-allocates a buffer, so the Vec struct itself always has the same size: a pointer and two usizes for the capacity and length.

size_of_val simply returns the size of the type of the passed value. Its return value only depends on the value itself in the case of dynamically-sized types such as slices and trait objects. Vec is not a DST.

3 Likes

Thanks for the awesome question.

1 Like