-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: Allocator trait should exclude Copy trait, require Drop trait, and get mutably borrowed on allocations #136
Comments
you don’t write much about this scenario; it works, all good
let’s address the issues you think you see:
this is not a valid allocator at all, at least in the sense of implementing the
it’s not a valid allocator regardless of whether or not it implements If it’s unsound for some allocators to be However using data on the stack for allocation is an intended (and supported) use case, see more below.
This case is indeed problematic. As mentioned above, this particular allocator must thus not implement Requiring some sort of scoping for such usage, as in e.g.
is indeed the correct idea to combine lightweight sharing with destructors, and indeed you almost get ther:
The only issue is the mutability. If you really write pub fn new_in(x: T, alloc: &A) -> Self let mut a = AltAlloc::default();
let ab1: Box<u32,AltAlloc>=Box::new_in(1234,&a);
let ab2: Box<u32,AltAlloc>=Box::new_in(4321,&a);
// Rust will drop things in the order of: ab2, ab1, a.
// This works fine even if `AltAlloc` is implemented via slicing an internal huge array on stack. That would work! How does it compare to the actual API? Here’s the secret: The current API is merely a generalization of the above! This is all because of this blanket impl<A> Allocator for &A
where
A: Allocator + ?Sized,
{ … } which makes it so that “when So the above code isn’t changed much, as the below will work today: pub fn new_in(x: T, alloc: A) -> Self let mut a = AltAlloc::default();
let ab1: Box<u32,&AltAlloc>=Box::new_in(1234,&a);
let ab2: Box<u32,&AltAlloc>=Box::new_in(4321,&a);
// Rust will drop things in the order of: ab2, ab1, a.
// This works fine even if `AltAlloc` is implemented via slicing an internal huge array on stack. Now, the
|
You might be interested in the storage API proposal #93 and related discussions, though not much progress has been made afaict. |
Neither does current
Allocator
trait excludeCopy
trait nor does it requireDrop
trait.Scenario 1: No implementation of
Copy
Only one allocation is allowed in this scenario. The following example won't compile.
Scenario 2: No implementation of
Drop
, butCopy
is implementedThis can cause some issues, though the following example will compile.
Waste of Resource if
AltAlloc
is implemented by slicing huge internal arrayAssume
AltAlloc
is an array ofu8
:This
AltAlloc
might not need a realDrop
trait implementation. But theCopy
trait will make this allocator to be created more than once. In above example, there are two allocators actually created. In other words, 128K was allocated, rather than 64K.Use After Free
ifAltAlloc
is implemented by slicing referenced internal arrayAssume
AltAlloc
includes a pointer tou8
:In this case, using
Copy
trait is fine because it only copies a pointer. It won't cause repetitive huge memory allocations. However, thisAltAlloc
requires something likeDrop
trait. SinceCopy
trait is implemented,Drop
trait can't be implemented. Assume adestroy
method is implemented:Then it would cause
Use-After-Free
while dropping:The only workaround is via scoping:
If
Drop
trait is implemented, thendestroy
method won't be required.However,
Copy
trait can't co-exist withDrop
trait. That's because it would cause doubled-free ifAltAlloc
contains only a pointer.Idea: Allocators should get borrowed
If allocators are borrowed, then
Copy
trait won't be needed. I thinkAllocator
trait should excludeCopy
trait.Same principle can be applied on
String
,Vec
, etc.The text was updated successfully, but these errors were encountered: