The former uses internal alloc API, and the latter uses system alloc API. Vec
, Box
uses the former.
Is the former implicitly replaced by the latter when there is std? What is the internal alloc API when there is std?
The former impls core::alloc::Allocator
, the latter impls core::alloc::GlobalAlloc
, but there is neither impl<T: Allocator> for GlobalAlloc
nor impl<T: GlobalAlloc> for Allocator
.
Before we go any further: the core
and alloc
crates are (almost completely) subsets of std
. So don't worry about the crate name — the modules are the same regardless of which crate you access them from, except that some items are only in alloc
or only in std
and not in core
.
Now, about the types:
-
Suppose you are thinking about choosing or implementing the global memory allocator used by Rust code by default. In this case, you care about the
GlobalAlloc
trait.- To implement a global allocator, you implement
GlobalAlloc
. - To choose the global allocator your program uses, you use the
#[global_allocator]
attribute to declare the desired allocator, which must implementGlobalAlloc
.std::alloc::System
exists so that you can explicitly choose the system allocator, or can wrap it to add behavior (as noted in the documentation for that type).
- To implement a global allocator, you implement
-
Suppose you want to use “local” allocators that are not the declared global allocator. In that case, you care about the
std::alloc::Allocator
trait and its implementors. (Note that all of this is still unstable, nightly-only).std::alloc::System
implementsAllocator
, so you can use specifically the system allocator, regardless of what the global allocator is.std::alloc::Global
implementsAllocator
, so you can use the registered global allocator.- You can also use an
Allocator
implementation that is neither of the above.
Is the former implicitly replaced by the latter when there is std?
The difference between “std” and “no std” environments is that the latter
- have no
std::alloc::System
since they don't havestd
and that's one of the items not in thealloc
crate, and - have no
#[global_allocator]
declared, so if you want to use a global allocator without std you have to declare one yourself.
But the traits are the same, and Global
exists in the alloc
crate, so you can use it as an Allocator
if you declare a global allocator.
The former impls
core::alloc::Allocator
, the latter implscore::alloc::GlobalAlloc
, but there is neitherimpl<T: Allocator> for GlobalAlloc
norimpl<T: GlobalAlloc> for Allocator
.
Right. The only way GlobalAlloc
s get used is as #[global_allocator]
. There is always exactly one of those. Then, if you want an Allocator
that is the global allocator, you don't pass an instance of it — you pass Global
which does implement Allocator
.
Note that all of this except for GlobalAlloc
and System
is unstable — because it's not certain that it's the right design yet. What I've written above is how it currently works.
Haven't noticed this before.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.