有没有办法预先泄漏价值?

llo*_*giq 5 memory-leaks rust

我目前正在研究使用数组做更多的事情,但我认为如果我们被允许以某种方式转换到Leaked<T>前面的阵列中,那么这些操作的性能可能会更好,只有在函数结束时才会泄漏它.这将让我们使用泄漏放大,而a)引入不安全和b)设置a catch_panic(_).这在Rust中是否有可能?

例如,从迭代器创建一个通用数组(这显然不起作用):

#[inline]
fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N>
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> {
     unsafe {
        // pre-leak the whole array, it's uninitialized anyway
        let mut res : GenericArray<Leaked<T>, N> = std::mem::uninitialized();
        let i = list.into_iter();
        for r in res.iter_mut() {
            // this could panic anytime
            std::ptr::write(r, Leaked::new(f(i.next().unwrap())))
        }
        // transmuting un-leaks the array
        std::mem::transmute::<GenericArray<Leaked<T>, N>,
                              GenericArray<T, N>>(res)
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该注意,如果我们要么编译时可以访问大小,T要么可以隐藏其内部类型(如Leaked<T>示例中所示),这是完全可行的.

mal*_*rbo 3

可以使用nodrop,但它可能会泄漏。

fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N>
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> {
     unsafe {
        // pre-leak the whole array, it's uninitialized anyway
        let mut res : NoDrop<GenericArray<T, N>> = NoDrop::new(std::mem::uninitialized());
        let i = list.into_iter();
        for r in res.iter_mut() {
            // this could panic anytime
            std::ptr::write(r, f(i.next().unwrap()))
        }
        res.into_inner()
    }
}
Run Code Online (Sandbox Code Playgroud)

假设第一项 ( a) 被消耗i并写入后r,发生了恐慌。剩余的物品i将会掉落,但物品a不会。虽然内存泄漏并不被认为是不安全的,但它是不可取的。

我认为问题链接中描述的方法是可行的方法。它类似于VecArrayVec实现。我正在编写的数组库中使用类似的方法。