---
title: アロケータとメモリレイアウト
url: https://doc.liz6.com/ja/rust/04-smart-pointers-and-memory/03-allocator-and-memory-layout
locale: ja
area: rust
tags:
- rust
- smart-pointers-and-memory
date: 2026-06-30
modified: 2026-07-16
description: 'Rust はデフォルトでシステムの malloc/free を使用しますが、GlobalAlloc トレイトを実装してグローバルアロケータを置き換えたり、特定コンテナにカスタムアロケータを指定したりできます。Layout はメモリサイズとアライメントを記述し、Pin は値の移動を防止します（自己参照型や非同期 Future に不可欠）。#[repr(align)] および #[repr(C)] によりメモリレイアウトを精密に制御できます。'
---

# アロケータとメモリレイアウト

> Rust はデフォルトでシステムの malloc/free を使用しますが、GlobalAlloc トレイトを実装してグローバルアロケータを置き換えたり、特定コンテナにカスタムアロケータを指定したりできます。Layout はメモリサイズとアライメントを記述し、Pin は値の移動を防止します（自己参照型や非同期 Future に不可欠）。`#[repr(align)]` および `#[repr(C)]` によりメモリレイアウトを精密に制御できます。

## デフォルトアロケータ

Rust はデフォルトでシステムの `malloc/free`（Linux では glibc の ptmalloc2）を使用しますが、置き換えることができます。`GlobalAlloc` トレイトを実装し、`#[global_allocator]` でマークします：

```rust
use std::alloc::{GlobalAlloc, Layout, System};

struct MyAllocator;
unsafe impl GlobalAlloc for MyAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        // 割り当てロジックの実装: 事前に確保したバッファから切り出す、または mmap を呼び出す、など
    }
    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        // 解放ロジックの実装
    }
}

#[global_allocator]
static GLOBAL: MyAllocator = MyAllocator;
```

一般的な代替アロケータ：`mimalloc`（Microsoft、フラグメンテーションが低い）、`jemalloc`（FreeBSD、マルチスレッド最適化済み）、`snmalloc`（Microsoft Research、メッセージパッシングベース）。

## Layout: 割り当てリクエストの記述

アロケータは直接「N バイトください」というリクエストを受け取るのではなく、サイズとアライメントを含む `Layout` 構造体を受け取ります：

```rust
use std::alloc::Layout;
let layout = Layout::new::<u64>();   // size=8, align=8
let layout2 = Layout::from_size_align(1024, 64).unwrap();
```

アロケータは、アライメント要件を満たすメモリを返さなければなりません。割り当てに失敗した場合は、`null` を返します（パニックしません）。

## allocator API: 手動割り当て

```rust
use std::alloc::{alloc, dealloc, Layout};
let layout = Layout::new::<u64>();
let ptr = unsafe { alloc(layout) as *mut u64 };
unsafe { *ptr = 42 };
unsafe { dealloc(ptr as *mut u8, layout) };
```

これは、型安全な Layout パラメータが追加された C の `malloc/free` にほぼ相当します。ほとんどのコードでは `alloc` を直接呼び出す必要はありません。`Box`、`Vec`、`String` などが既に処理してくれます。

## Pin: 移動の防止

Rust のムーブセマンティクスでは、任意の値が新しいアドレスに `memcpy` される可能性があります。しかし、自己参照構造体（struct のフィールドが同じ struct の別のフィールドを参照している場合）では、ムーブ後に参照がダングリングになります。`Pin` は、ピン留めされた値がそれ以上ムーブされないことを保証します：

```rust
use std::pin::Pin;
// 典型的な自己参照構造体（簡略化版）:
struct SelfRef { value: String, ptr: *const String }
// 構築時に ptr は value を指しますが、SelfRef がムーブされると → ptr がダングリングする
// Pin<Box<SelfRef>> は SelfRef がムーブされないことを保証し、安全です
```

`async fn` から生成される Future は典型的な自己参照構造体です。これは、await ポイントより前のローカル変数を参照します。`Pin<&mut Future>` は、poll 中に Future がムーブされないことを保証します。これが async/await コンパイラの内部実装の基盤です。

## 参考

- **Rustonomicon**: アロケータ、Pin
- **RFC 1398**: カスタムアロケータ
- **RFC 2349**: Pin

*Keywords: GlobalAlloc, Layout, custom allocator, Pin, self-referential, #[repr(align)], alloc API*
