Created a small rust program to understand the memory allocation. Just wanted to understand if the data types use the memory area they are supposed to get allocated to.
fn main() {
// stack
let num: u8 = 89;
// heap
let boxed_num = Box::new(89);
// stack
let num2: u8 = 99;
//heap
let boxed_num2 = Box::new(99);
// heap
let s = String::from("hello");
println!(
"
num: {:p}
boxed_num: {:p}
num2: {:p}
boxed_num2: {:p}
string: {:p}
",
&num, &boxed_num, &num2, boxed_num2, &s
);
}
I was expecting num
and num2
to get allocated on stack
And boxed_num
, boxed_num2
and s
on heap
the program output was
num: 0x7fff40d38def
boxed_num: 0x7fff40d38df0
num2: 0x7fff40d38dff
boxed_num2: 0x55cf316c4af0
string: 0x7fff40d38e08
But I was amazed when I checked the proc maps. It was
cat /proc/6182/maps
55cf316c4000-55cf316e5000 rw-p 00000000 00:00 0 [heap]
7fff40d19000-7fff40d3b000 rw-p 00000000 00:00 0 [stack]
How it could be possible? only boxed_num2 seems to be on heap and every other var goes to stack. Took multiple iterations. This pattern is consistent.
Why only
boxed_num2
on heap?
Why
boxed_num
ands
on stack?
Both boxed_num
, boxed_num2
and s
are objects that live on the stack and point to data on the heap.
To get the heap part of Box
/String
, you need to call Box::as_ref()
or String::as_bytes()
.
The reason why boxed_num2
was shown on the heap was that you didn't add a &
to it, causing an automatic dereference to its heap value.
This is because {:p}
expects a reference, and boxed_num2
can implicitely be converted into its heap value reference.
Here you go:
fn main() {
// stack
let num: u8 = 89;
// heap
let boxed_num = Box::new(89);
// stack
let num2: u8 = 99;
//heap
let boxed_num2 = Box::new(99);
// heap
let s = String::from("hello");
println!(
"
num: {:p}
boxed_num: {:p}
num2: {:p}
boxed_num2: {:p}
string: {:p}
",
&num,
boxed_num.as_ref(),
&num2,
boxed_num2.as_ref(),
s.as_bytes(),
);
}
num: 0x7ffd1375d7cf
boxed_num: 0x557006c71ad0
num2: 0x7ffd1375d7df
boxed_num2: 0x557006c71af0
string: 0x557006c71b10