3 个版本
0.1.2 | 2024年3月25日 |
---|---|
0.1.1 | 2024年3月24日 |
0.1.0 | 2024年3月24日 |
#159 in 测试
在 compact-rc 中使用
19KB
281 行
dropcount
统计析构函数调用。
Rust 是内存安全的,但在不安全块中可能会发生内存错误。在不安全编程中,通常需要实现我们自己的数据结构,如容器或智能指针。这个crate提供了一种通过计数析构函数调用来测试内存泄漏或多次析构的方法。
如果仅用于测试,请在 Cargo.toml 的 'dev-dependencies' 部分使用如下;
# Cargo.toml
[dev-dependencies]
dropcount = "0.1"
用法
// Create a pair of counter and viewer.
// They share an internal count value.
let (counter, viewer) = dropcount::new();
// The viewer returns 0.
// The counter has not been destructed.
assert_eq!(viewer.get(), 0);
// Destruct the counter.
drop(counter);
// The viewer returns 1 after destructing the counter.
assert_eq!(viewer.get(), 1);
示例
测试智能指针
测试智能指针析构其值恰好一次的示例。
use std::rc::Rc;
fn test_rc() {
let (counter, viewer) = dropcount::new();
// rc1 and rc2 shares the counter object.
let rc1 = Rc::new(counter);
let rc2 = rc1.clone();
// The counter is not destructed.
assert_eq!(viewer.get(), 0);
drop(rc1);
// The counter is not destructed.
assert_eq!(viewer.get(), 0);
drop(rc2);
// The counter is destructed.
assert_eq!(viewer.get(), 1);
}
测试集合
测试容器析构每个值恰好一次的示例。
use std::collections::HashMap;
fn test_hashmap() {
let (counters, viewers) = dropcount::new_vec(5);
let mut map: HashMap<usize, dropcount::Counter> =
counters.into_iter().enumerate().collect();
assert_eq!(viewers[0].get(), 0);
assert_eq!(viewers[1].get(), 0);
assert_eq!(viewers[2].get(), 0);
assert_eq!(viewers[3].get(), 0);
assert_eq!(viewers[4].get(), 0);
// Remove an element.
map.remove(&2);
// The viewer paired with the removed element returns 1.
assert_eq!(viewers[0].get(), 0);
assert_eq!(viewers[1].get(), 0);
assert_eq!(viewers[2].get(), 1);
assert_eq!(viewers[3].get(), 0);
assert_eq!(viewers[4].get(), 0);
// Drop the container.
drop(map);
// All viewers returns 1 after the container is dropped.
assert_eq!(viewers[0].get(), 1);
assert_eq!(viewers[1].get(), 1);
assert_eq!(viewers[2].get(), 1);
assert_eq!(viewers[3].get(), 1);
assert_eq!(viewers[4].get(), 1);
}
多线程支持
这个crate支持多线程。使用原子整数作为内部计数器值。因此,可以捕获多线程中的销毁次数。
use std::thread;
fn test_multi_thread() {
let (counter, viewer) = dropcount::new();
let handle = thread::spawn(move || {
drop(counter);
});
handle.join().expect("Error in thread.");
assert_eq!(viewer.get(), 1);
}