比如,我们经常看到Vec类型,但取转其裸指针,经常会看到into_boxed_slice()方法,这是为何?
use std::{fmt, slice};
use std::mem::size_of_val;
#[derive(Clone, Copy)]
struct RawBuffer {
ptr: *mut u8,
len: usize,
}
impl From<Vec<u8>> for RawBuffer {
fn from(vec: Vec<u8>) -> Self {
let slice = vec.into_boxed_slice();
Self {
len: slice.len(),
// into_raw 之后,Box 就不管这块内存的释放了,RawBuffer 需要处理释放
ptr: Box::into_raw(slice) as *mut u8,
}
}
}
其实,你看标准文档,就很清楚,
pub fn into_boxed_slice(self) -> Box<[T], A>
//Converts the vector into Box<[T]>.
//If the vector has excess capacity, its items will be moved into a newly-allocated buffer with exactly the right capacity.
也就是说,转成了Box<[T]>后,指针所指向的类型,更简短了,丢弃多余的 capacity。
use std::{fmt, slice};
// 从*mut u8 恢复
fn as_ref<'a,T>(pointer: *mut T, len: usize) -> &'a [T] {
unsafe { slice::from_raw_parts(pointer, len) }
}
// 从vec<T>转化Box<[T]>后得到相应的裸指针
fn get_raw_pointer_from_vec_by_box<T>(vec:Vec<T>) ->*mut T{
let slice = vec.into_boxed_slice();
Box::into_raw(slice) as *mut T
}
// 从vec<T>的as_mut_ptr()得到的裸指针
fn get_raw_pointer_from_vec_by_as_mut<T:Copy>( vec:&mut Vec<T>) ->*mut T{
let ptr = vec.as_mut_ptr();//不能直接用,相当于是一个初始化的指针
let counts = vec.len();
let size = vec.capacity();
// Initialize elements via raw pointer writes, then set length.
unsafe {
for i in 0..counts {
*ptr.add(i) = vec[i];
}
vec.set_len(size);
}
ptr
}
fn main(){
//尽管size_of_val只是测试真实占用内存;不包括预分配的内存空间
let vec_base = vec![1_u8, 2, 3];
println!("vec_base size of val :{:?}",size_of_val(&vec_base));
let mut vec = Vec::with_capacity(100);//预分配空间
vec.extend([1_u8, 2, 3]);
println!("vec size of val :{:?}",size_of_val(&vec));
let vec0 = vec.clone();
let slice = vec0.into_boxed_slice() ;// Box<[u8]> ,clone()不会影响vec值的存在
assert_eq!(slice.clone().into_vec().capacity(), 3); // slice clone后不会影响slice值存在
// 指针类型1:通过box[T]->转换成&[T]
let vec1 = vec.clone();
let pointer_from_box = get_raw_pointer_from_vec_by_box(vec1);//获得相应的*mut u8
let slice_object_from_box = as_ref(pointer_from_box,slice.len()) ;
println!("slice_object_from_box :{:?} ",slice_object_from_box);
// 指针类型2:通过 as_mut 直接转 *mut T,再转换成&[T]
let mut vec2 = vec.clone();
let pointer_from_as_mut = get_raw_pointer_from_vec_by_as_mut(&mut vec2);
let slice_object_from_as_mut = as_ref(pointer_from_as_mut,vec.len());//vec.capacity()) ;
println!("slice_object_from_as_mut: {:?} ",slice_object_from_as_mut);
}
看看输出了啥?文章来源:https://www.toymoban.com/news/detail-619517.html
Running `target/debug/playground`
Standard Output
vec_base size of val :24
vec size of val :24
slice_object_from_box :[1, 2, 3]
slice_object_from_as_mut: [1, 2, 3]
上面,还可以看到,实际分配内存和预分配内存不一样。文章来源地址https://www.toymoban.com/news/detail-619517.html
到了这里,关于Rust: Vec类型的into_boxed_slice()方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!