Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Dropを走らせないRustのメモリ管理
Search
estie | エスティ
October 19, 2026
1
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Dropを走らせないRustのメモリ管理
estie | エスティ
October 19, 2026
More Decks by estie | エスティ
See All by estie | エスティ
AI時代 自由なデータ利活用とデータ保護を両立するバックエンド設計
estie
0
21
自社のレビュー履歴からAIコードレビュアーをつくる方法
estie
5
1.7k
ボトルネックは人間 ~その負担をどこまで AI に渡せるか~
estie
0
86
自分の価値が出せる場所に越境せよ
estie
0
170
AIに障害切り分けを全部やってもらった。 。 。 。
estie
1
580
Claude Code の /loop を活用する
estie
0
220
【estie x AI】 AI戦略の現在地と未来
estie
0
140
不動産業界における業界特化のデータ整備とAI活用 ─Vertical DataとVertical AI─
estie
1
1.1k
AI活用で高速化するプロダクト開発
estie
1
140
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
590
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Practical Orchestrator
shlominoach
192
12k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
280
The Limits of Empathy - UXLibs8
cassininazir
2
720
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Optimising Largest Contentful Paint
csswizardry
37
4k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
560
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Transcript
Drop を走らせない Rust のメモリ管理 Rust、何もわからない… #15 @garasubo © 2026 estie
Inc. 0
発表者紹介 • ガラスボー(@garasubo) • OSなどの低レイヤー分野がきっかけでRustをはじめた • 遊戯王マスターデュエル、ファイアーエムブレムが大好き • 株式会社estie •
2026年6月入社 • 社内に残っているRailsアプリをRustに置き換えている © 2026 estie Inc. 1
1. 前提 • 所有権とDrop • Rust はリークがないことを保証しない 2. Dropを止めるAPI 3.
まとめ © 2026 estie Inc. 2
前提 / 所有権とスコープ 所有者がスコープを抜けると drop される • 値には所有者となる変数がいる • 所有者がスコープを抜けると値が
drop される • 確保していたメモリ領域も解放される • Drop::drop に書いた処理も実行される { let a = String::from("hello"); println!("{a}"); // ここで a が drop → メモリ解放 } // 以降 a にはアクセスできない © 2026 estie Inc. 3
前提 / メモリリーク Rust はメモリリークがないことを保証していない let file = File::open("foo.txt").unwrap(); mem::forget(file);
// drop されず、close もされない mem::forget は safe な関数 リークはメモリ安全性の保証の範囲外。Rust はリークに対して寛容 © 2026 estie Inc. 4
Drop を止める API Dropを止める様々なAPIが用意されている • Box::leak • 生ポインタ • ManuallyDrop
• MaybeUninit © 2026 estie Inc. 5
Drop を止める API / Box::leak Box::leakでstaticな参照をつくる • &'static mut な参照が返ってくる
• forget と違い、その後も値を操作できる • 実行中ずっと生存させたいときに便利 • 後でデストラクタを呼びたい用途には不向き • 完全にリークさせる前提の API © 2026 estie Inc. let x = Box::new(41); let r: &'static mut usize = Box::leak(x); // 値は生き続けているので操作できる *r += 1; assert_eq!(*r, 42); 6
Drop を止める API / 生ポインタ 生ポインタを活用するAPI let b = Box::new(String::from("hello"));
let p: *mut String = Box::into_raw(b); // b は move され、drop されない unsafe { (*p).push_str(", world"); assert_eq!(*p, "hello, world"); drop(Box::from_raw(p)); // Box に戻して drop → 中身もヒープも解放 } safe into_raw で生ポインタ化 © 2026 estie Inc. unsafe ポインタ経由で自由に操作 unsafe from_raw で戻して drop 7
Drop を止める API / 生ポインタ 生ポインタが必要になる代表例:FFI • C などの他言語にはライフタイムや所 有権を伝えられない
• C 側が持っている間に Rust が drop すると困る • into_raw で所有権ごと手放す • 解放は Rust に戻して行う • from_raw して drop • C の free() では解放しない pub struct Parser { /* ... */ } #[unsafe(no_mangle)] pub extern "C" fn parser_new() -> *mut Parser { Box::into_raw(Box::new(Parser::new())) // C 側へ渡す } #[unsafe(no_mangle)] pub unsafe extern "C" fn parser_free(p: *mut Parser) { if !p.is_null() { drop(unsafe { Box::from_raw(p) }); // Rust で解放 } } // C 側: Parser *p = parser_new(); ... parser_free(p); © 2026 estie Inc. 8
Drop を止める API / ManuallyDrop ManuallyDrop: drop するタイミングを自分で決める • 包んだ値は自動で
drop されない • into_inner で元に戻すのは safe • ManuallyDrop::drop は unsafe • drop 後も変数自体には触れてしまう • 二重 drop は未定義動作 • drop 後の使用も未定義動作 © 2026 estie Inc. // safe:包む・元に戻す let x = ManuallyDrop::new(Box::new(())); let b: Box<()> = ManuallyDrop::into_inner(x); // unsafe:自分で drop する let mut x = ManuallyDrop::new( String::from("unsafe Rust")); unsafe { ManuallyDrop::drop(&mut x); } println!("{}", *x); // 未定義動作! 9
Drop を止める API / ManuallyDrop 実例:BufWriter::into_parts // Rust 標準ライブラリ BufWriter
より pub fn into_parts(self) -> (W, Result<Vec<u8>, WriterPanicked>) { let mut this = ManuallyDrop::new(self); // 本体の drop を止める let buf = mem::take(&mut this.buf); let buf = if !this.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) }; // SAFETY: this は drop されないので二重 drop にならない let inner = unsafe { ptr::read(&this.inner) }; (inner, buf) } Drop 実装型のフィールドは個別に move できない → 包んで取り出す © 2026 estie Inc. 10
Drop を止める API / MaybeUninit MaybeUninit:初期化前かもしれない値 • Rustは確保と初期化を同時に行うのが前提 (RAII) •
確保と初期化をあえて分けるのに使える • フィールドごとの初期化 • 配列の要素の初期値 • 後始末はプログラマの責務 • assume_init struct Config { name: String, port: u16 } let mut cfg = MaybeUninit::<Config>::uninit(); let p = cfg.as_mut_ptr(); let cfg: Config = unsafe { (&raw mut (*p).name).write(String::from("server")); (&raw mut (*p).port).write(8080); cfg.assume_init() }; • assume_init_drop © 2026 estie Inc. 11
まとめ 紹介したAPIの早見表 API 元に戻す方法 解放されるのは unsafe な操作 向いている用途 mem::forget 戻せない
解放されない なし とにかく drop を止める Box::leak 戻さない前提 解放されない なし 実行中ずっと生かす値 生ポインタ from_raw 元の型に戻して drop した時 戻す・参照外し FFI、自前のデータ構造 ManuallyDrop into_inner(safe) 自分で drop した時 ManuallyDrop::drop フィールドの取り出し MaybeUninit assume_init 初期化後、自分で © 2026 estie Inc. assume_init 系 段階的な初期化 12
まとめ • Rust はメモリリークを保証しない。Drop を止める API がいくつもある • Drop を止めたい理由でAPIを使い分ける
• ずっと生かしたい → Box::leak • 所有権の外で扱いたい → into_raw / from_raw • drop のタイミングを決めたい → ManuallyDrop • 未初期化の値を扱いたい → MaybeUninit • © 2026 estie Inc. プログラマの責務で自由にできる。メモリ管理は奥が深い! 13