h2o2
h2o2

Reputation: 106

Why does calling Box::new twice without storing the result allocate the same heap address?

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

Answers (1)

Shepmaster
Shepmaster

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 [Boxes] 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

Related Questions