alloc
allocを使うためには、グローバル(ヒープ)アロケータを実装しなければなりません。
#![no_main]
#![no_std]
extern crate alloc;
extern crate panic_halt as _;
use alloc::string::ToString;
use alloc::vec::Vec;
use buddy_system_allocator::LockedHeap;
#[global_allocator]
static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();
static mut HEAP: [u8; 65536] = [0; 65536];
pub fn entry() {
// SAFETY: `HEAP` is only used here and `entry` is only called once.
unsafe {
// アロケーターにメモリを割り当てます。
HEAP_ALLOCATOR.lock().init(HEAP.as_mut_ptr() as usize, HEAP.len());
}
// これで、ヒープ割り当てを必要とする処理を実行できるようになりました。
let mut v = Vec::new();
v.push("A string".to_string());
}
buddy_system_allocatorはサードパーティのクレートで、単純なバディシステムアロケータです。その他にも利用できるクレートはありますし、自前で実装したり、別のアロケータに自分のコードをフックすることも可能です。- パラメータ定数
LockedHeapはアロケータの最大オーダを示します。この場合、2**32バイトの領域を確保することが可能です。 - もし依存関係にあるクレートが
allocに依存する場合、必ずバイナリファイルあたり一つだけのグローバルなアロケータが存在するようにしなければなりません。通常、これはトップレベルのバイナリを生成するクレートにより制御されます。 extern crate panic_halt as _という部分は、panic_haltクレートを確実にリンクし、パニックハンドラを利用可能にするために必要です。- この例で示したコードはビルドできますが、エントリポイントがないので実行することはできません。