Reputation: 106
I have the following code snippet:
fn test() {
let addr = Box::new(1024);
println!("{:p}", addr);
}
fn main(){
test();
test();
}
0x7fd2fa402b70
0x7fd2fa402b70
As the documentation explains, Box::new
will allocate memory on the heap and then place the argument into it. No matter how many times I call test()
, the program prints an identical address.
Why does Rust allocate the same heap address, even if the code is in an unsafe
block? Is this normal behavior?
Upvotes: 1
Views: 162
Reputation: 430634
Since you aren't storing the result beyond the test
function, the allocated memory is immediately freed. This allows the memory allocator to reuse the same address by the time of the second call.
I think current
Box::new
implementation have different behaviors from what I expect
Yes, that seems likely, but it's worth thinking about why you expect this certain behavior. To me, the demonstrated behavior makes sense.
or at least we should comment this "optimization" on [
Box
es] rustdoc
This isn't an optimization of Box
, by any means. The behavior to free the value as soon as it doesn't have an owner is part of the definition of the Rust language.
It could be considered an optimization of the underlying memory allocator in use at the moment. However, the allocator implementation makes sense to many programmers and it's not unique to Rust. For example, here's a similar program in C:
#include <stdio.h>
#include <stdlib.h>
int main() {
for (int i = 0; i < 10; i++) {
int32_t *v = malloc(sizeof(int32_t));
printf("%p\n", (void *)v);
free(v);
}
}
% clang -std=c17 -Wpedantic -Wall alloc.c
% ./a.out
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
Note that the implementation of the memory allocator is what ultimately causes the same address to be returned; it's possible to write a memory allocator where that's not true.
Upvotes: 6