バッファの固定プールからバッファを割り当て、割り当てを解除する単純なアロケータを作ろうとしています。単純なリソースで生涯エラーが発生するアロケータstruct
struct AllocatedMemory<'a> {
mem: &'a mut [u8],
next: Option<&'a mut AllocatedMemory<'a>>,
}
struct Alloc<'a> {
glob: Option<&'a mut AllocatedMemory<'a>>,
}
impl<'a> Alloc<'a> {
fn alloc_cell(mut self: &mut Alloc<'a>) -> &mut AllocatedMemory<'a> {
let rest: Option<&'a mut AllocatedMemory<'a>>;
match self.glob {
Some(ref mut root_cell) => {
rest = std::mem::replace(&mut root_cell.next, None);
}
None => rest = None,
}
match std::mem::replace(&mut self.glob, rest) {
Some(mut root_cell) => {
return root_cell;
}
None => panic!("OOM"),
}
}
fn free_cell(mut self: &mut Alloc<'a>, mut val: &'a mut AllocatedMemory<'a>) {
match std::mem::replace(&mut self.glob, None) {
Some(mut x) => {
let discard = std::mem::replace(&mut val.next, Some(x));
let rest: Option<&'a mut AllocatedMemory<'a>>;
}
None => {}
}
self.glob = Some(val);
}
}
fn main() {
let mut buffer0: [u8; 1024] = [0; 1024];
let mut buffer1: [u8; 1024] = [0; 1024];
{
let mut cell1: AllocatedMemory = AllocatedMemory {
mem: &mut buffer1[0..1024],
next: None,
};
let mut cell0: AllocatedMemory = AllocatedMemory {
mem: &mut buffer0[0..1024],
next: None,
};
let mut allocator = Alloc { glob: None };
allocator.free_cell(&mut cell1); //populate allocator with a cell
allocator.free_cell(&mut cell0); //populate allocator with another cell (why does this fail?)
let mut x = allocator.alloc_cell();
allocator.free_cell(x);
let mut y = allocator.alloc_cell();
let mut z = allocator.alloc_cell();
allocator.free_cell(y);
allocator.free_cell(z);
}
}
私は単純に、次のエラーが発生したcell0
を削除し、唯一の私の細胞プールに利用できるcell1
を持っているときにエラーが
error: `cell0` does not live long enough
allocator.free_cell(&mut cell0); //populate allocator with another cell (why does this fail?)
です:
error: allocator does not live long enough
let mut x = allocator.alloc_cell();
^~~~~~~~~
note: reference must be valid for the block suffix following statement 0 at 46:69...
next: None};
let mut cell0 : AllocatedMemory = AllocatedMemory{mem: &mut buffer0[0..1024],
next: None};
let mut allocator = Alloc {glob : None};
allocator.free_cell(&mut cell1); //populate allocator with a cell
//allocator.free_cell(&mut cell0); //populate allocator with another cell (why does this fail?)
note: ...but borrowed value is only valid for the block suffix following statement 2 at 49:48
let mut allocator = Alloc {glob : None};
allocator.free_cell(&mut cell1); //populate allocator with a cell
//allocator.free_cell(&mut cell0); //populate allocator with another cell (why does this fail?)
let mut x = allocator.alloc_cell();
allocator.free_cell(x);
...
error: aborting due to previous error
誰でも上の勧告を持っていますこのコードを修正してコンパイルする方法と、フリーリストに2つ以上の項目がある可能性があります。
配列への参照のリストを作成し、ポップすることができます。しばらく使用して、使用済み/終了値を空きリストに戻します。
ここでの動機付けは、#![nostd]
ディレクティブを使用するライブラリを構築することです。したがって、正しく動作するにはアロケータインターフェイスが必要です。
私は詳細を見ていませんが、これはリンクされたリストのようです。典型的な初心者の間違いは、親ノードがボックスで所有するのではなく、&または&mutを使って子ノードを借用することです。これはどんな助けですか? –
これは役に立ちます。しかし、私はlibstdクレートを必要とせずにこれをしたいと思っています。だからボックスは、私がここで私のために働かないと信じています。 – hellcatv
それは、何かが使われる前に、リストに借りられているすべてのものが生き残って、スタックに存在することができてうれしいです。だから私はここで実際に所有権を侵害しているわけではありません...デザインにはリスト構造の範囲外で同じ生涯を持つ細胞がたくさんあります。そうすれば、リスト構造は単にそれらを互いに参照させることができます。 starblueが指摘している問題は、スタック上の2つのアイテムが「同じ時刻」に生き残ることができないので、それ以降のアイテムは以前のアイテムを参照することができないということです。 – hellcatv