0

Briefly, some data types are stored on the stack, as the compiler knows how much memory they will require at run time. Other data types are more flexible, and are stored in the heap. The Pointer of the data stays on the stack, pointing to the heap data.

My question is, if the Vec data are on the heap, how is it that i32 (and other normally stack-stored types) can be accessed as if the actually were on the stack (copied by indexing).

In other words. It makes sense to me that I cannot move out String from the Vec, they don't implement Copy and are normally move. The same happens whem they are element of a Vec. However, i32 is normally copied, but why does this happen also when they are part of the vector data on the heap?

Please feel free to point out any conceptual error and point me to existing material if you think I missed someting. I have read The Rust Programming Language and checked around a bit.

fn main() {
    // int in stack
    let i: i32 = 1;
    let _ic = i;
    println!("{}", i);

    // String on heap
    let s: String = String::from("ciao cippina");
    let _sc = &s;
    println!("{}", s);

    // array and data on the stack
    let ari = [1, 2, 3];
    println!("{:?}", &ari);
    println!("a 0 {}", ari[0]);

    // array and Pointers on the stack, data on the heap
    let ars = [String::from("ciao"), String::from("mondo")];
    println!("{:?}", &ars);
    println!("a 0 {}", ars[0]);
    // let _ars_1 = ars[0];  // ERROR, cannot move out of array

    // Vec int, its Pointer on stack, all the rest on heap
    let veci = vec![2, 4, 5, 6];
    println!("{:?}", &veci);
    println!("a 0 {}", veci[0]);
    let _veci_1 = veci[0];  // NO ERROR HERE ??

    // Vec string, its Pointer on stack, all the rest on heap
    let vecs = vec![String::from("ciao"), String::from("mondo")];
    println!("{:?}", &vecs);
    println!("a 0 {}", vecs[0]);
    // let _vecs_1 = vecs[0];  // ERROR, cannot move out of Vec
}
trincot
  • 317,000
  • 35
  • 244
  • 286
Peruz
  • 403
  • 3
  • 10
  • Yes, the motivation is the same that Vivek pointed out here. I guess I was getting the woring idea that copying from the heap was slower and so move was preferred, no matter the type (copyable or not). Thaks all for the comments and answer. – Peruz May 17 '20 at 18:21

1 Answers1

2

Just because element of a vector lives on a heap doesn't mean that compiler can't know the size of the element. It doesn't matter where element lives, if a type is "copyable", it can be copied from stack -> heap and vice-versa.

In your case, i32 occupies 4 bytes whether on heap or on stack (ignores alignment concerns)

apatniv
  • 1,771
  • 10
  • 13