使用slice::from_raw_parts_mut和ptr::drop_in_place in rust进行内存释放
我在网上看到一段代码,它使用使用slice::from_raw_parts_mut和ptr::drop_in_place in rust进行内存释放,rust,slice,Rust,Slice,我在网上看到一段代码,它使用std::slice::from_raw_parts_mut()和std::ptr::drop_in_place()的组合删除分配的内存。下面是一段代码,分配一个由十个整数组成的数组,然后对其进行反分配: use std::{ alloc::{alloc, Layout}, ptr::NonNull, }; fn main() { let len: usize = 10; let layout: Layout = Layout::ar
std::slice::from_raw_parts_mut()
和std::ptr::drop_in_place()
的组合删除分配的内存。下面是一段代码,分配一个由十个整数组成的数组,然后对其进行反分配:
use std::{
alloc::{alloc, Layout},
ptr::NonNull,
};
fn main() {
let len: usize = 10;
let layout: Layout = Layout::array::<i32>(len).unwrap();
let data: NonNull<i32> = unsafe { NonNull::new(alloc(layout) as *mut i32).unwrap() };
unsafe {
std::ptr::drop_in_place(std::slice::from_raw_parts_mut(data.as_ptr(), len));
}
}
使用std::{
alloc::{alloc,Layout},
ptr::非空,
};
fn main(){
设len:usize=10;
let layout:layout=layout::array::(len).unwrap();
let data:NonNull=unsafe{NonNull::new(alloc(layout)as*mut i32).unwrap()};
不安全{
std::ptr::drop_in_place(std::slice::from_raw_parts_mut(data.as_ptr(),len));
}
}
std::slice::from_raw_parts_mut()
的返回类型是一个可变片&mut[T]
,但是std::ptr::drop_in_place()
的参数是*mut
。在我看来,转换是自动进行的。我很确定我错过了什么,因为这是不允许的。有人能解释一下这里到底发生了什么吗?当您编写std::slice::from_raw_parts_mut(data.as_ptr(),len)
时,您正在构建&mut[i32]
类型的值
然后将其传递给drop\u in\u place()
,它或多或少定义为:
fn drop_in_place<T: ?Sized>(to_drop: *mut T)
fn放置到位(放置:*mut T T)
因此,您正在将一个&mut[i32]
强制为一个*mut
,这可以通过两个步骤来解决:有一个来自的自动强制,然后T
被解析为[i32]
,这是实际调用drop
的类型
(您可能认为从引用到指针的自动强制是危险的,不应该是自动的,但实际上是完全安全的。不安全的通常是您事后对指针所做的操作。实际上,原始指针有两种安全的用法,例如std::ptr::eq
或std::ptr::hash
)
切片通过简单地迭代元素并在每个元素中调用Drop\in\u place
来实现Drop::Drop
。这是一种避免手动编写循环的聪明方法
但请注意关于此代码的几点:
drop\u in_place
将在片的每个元素上调用drop::drop
,但由于它们属于i32
类型,因此实际上是禁止操作的。我猜您的原始代码使用了泛型类型drop\u in\u place
不会释放内存,因此需要调用std::alloc::dealloc
实际上,有一个从
&mut[T]
到*mut[T]
的转换。你认为这段代码的哪一步应该失败?@rodrigo将&mut[T]
隐式转换为*mut[T]
。我是个新手,但我找不到任何提到这种隐式转换的文档。还请注意,在本例中,转换是从&mut[T]
到*mut[T
的转换,而不是您提到的(&mut[T]
到*mut[T]
)从引用到原始指针的隐式转换(强制)。我认为你错了:drop\u in_place()
采用*mut
但是T
是从上下文自动推导出来的,如果你传入&mut[i32]
,那么T
将解析为[i32]
,因此你正在从&mut[i32]
转换为*mut[i32]
@rodrigo你能写一个答案让我接受吗。