error: memory leaked: alloc217 (Rust heap, size: 40, align: 8), allocated here:
Miri がメモリリークを検出した場合のエラー。
確保したメモリがプログラム完了時点で未解放、かつグローバルな static 領域からそれらへとポインタを辿って到達不可能な場合、メモリリークと判定される。
unsafe の誤用
unsafe の誤用によりメモリ管理が破綻するパターン。
以下では、unsafe な機能で Rc の参照カウンタを強引に操作している。
use std::rc::Rc;
fn main() {
let rc = Rc::new(42);
let ptr = Rc::into_raw(rc);
unsafe {
Rc::increment_strong_count(ptr);
}
}
error: memory leaked: alloc207 (Rust heap, size: 24, align: 8), allocated here:
--> C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\rc.rs:412:27
|
412 | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value }))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: BACKTRACE:
= note: inside `std::rc::Rc::<i32>::new` at C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\rc.rs:412:27: 412:96
note: inside `main`
--> src\main.rs:4:14
|
4 | let rc = Rc::new(42);
| ^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check
参照カウンタ方式の型 (Rc や Arc など) が循環参照して解放されないパターン。
以下では、単方向リンクの末尾が先頭と接続され、Rc が循環参照している。
use std::rc::Rc;
use std::cell::RefCell;
fn main() {
// Construct links.
let n1 = &mut LinkNode::new(1);
let n2 = &mut LinkNode::new(2);
n1.borrow_mut().set_next(n2);
n2.borrow_mut().set_next(n1);
// Assert links.
let n1_next = n1.borrow().next();
assert_eq!(n1_next.borrow().value, n2.borrow().value);
}
struct LinkNode {
value: i32,
next: Option<Rc<RefCell<LinkNode>>>,
}
impl LinkNode {
pub fn new(value: i32) -> Rc<RefCell<LinkNode>> {
let next = None;
Rc::new(RefCell::new(Self { value, next }))
}
pub fn next(&self) -> Rc<RefCell<LinkNode>> {
self.next.as_ref().unwrap().clone()
}
pub fn set_next(&mut self, node: &Rc<RefCell<LinkNode>>) {
self.next = Some(node.clone());
}
}
error: memory leaked: alloc217 (Rust heap, size: 40, align: 8), allocated here:
--> C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\rc.rs:412:27
|
412 | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value }))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: BACKTRACE:
= note: inside `std::rc::Rc::<std::cell::RefCell<LinkNode>>::new` at C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\rc.rs:412:27: 412:96
note: inside `LinkNode::new`
--> src\main.rs:24:9
|
24 | Rc::new(RefCell::new(Self { value, next }))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `main`
--> src\main.rs:6:19
|
6 | let n1 = &mut LinkNode::new(1);
| ^^^^^^^^^^^^^^^^
error: memory leaked: alloc285 (Rust heap, size: 40, align: 8), allocated here:
--> C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\rc.rs:412:27
|
412 | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value }))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: BACKTRACE:
= note: inside `std::rc::Rc::<std::cell::RefCell<LinkNode>>::new` at C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\rc.rs:412:27: 412:96
note: inside `LinkNode::new`
--> src\main.rs:24:9
|
24 | Rc::new(RefCell::new(Self { value, next }))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `main`
--> src\main.rs:7:19
|
7 | let n2 = &mut LinkNode::new(2);
| ^^^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check