Rust 我可以使用Box::from_raw将内存从Vec::释放到_装箱_片中吗?
I以下代码用于将字节数组返回给C:Rust 我可以使用Box::from_raw将内存从Vec::释放到_装箱_片中吗?,rust,unsafe,Rust,Unsafe,I以下代码用于将字节数组返回给C: #[repr(C)] 结构缓冲区{ 数据:*mut u8, len:使用, } 外部“C”fn生成_数据()->缓冲区{ 让mut buf=vec![0;512]。放入装箱的切片(); 设data=buf.as_mut_ptr(); 设len=buf.len(); std::mem::忘记(buf); 缓冲区{数据,len} } 外部“C”fn自由度(buf:缓冲区){ 设s=safe{std::slice::from_raw_parts_mut(buf.da
#[repr(C)]
结构缓冲区{
数据:*mut u8,
len:使用,
}
外部“C”fn生成_数据()->缓冲区{
让mut buf=vec![0;512]。放入装箱的切片();
设data=buf.as_mut_ptr();
设len=buf.len();
std::mem::忘记(buf);
缓冲区{数据,len}
}
外部“C”fn自由度(buf:缓冲区){
设s=safe{std::slice::from_raw_parts_mut(buf.data,buf.len)};
设s=s.as_mut_ptr();
不安全{
方框::来自未加工材料;
}
}
我注意到free\u buf
函数使用缓冲区,而不是*mut u8
。这是故意的吗
free\u buf
功能是否可以简化为:
不安全外部“C”fn自由(ptr:*mut u8){
框::来自原始(ptr);
}
您可以正确地注意到,C runtimefree
函数只将指向要释放的内存区域的指针作为参数
但是,你不能直接打电话给他。事实上,Rust有一个抽象层,抽象出实际使用的内存分配器:
提供这样一个抽象的原因是允许使用其他分配器,事实上,它是为了替换操作系统提供的默认分配器
要求任何分配器跟踪块的长度以允许在不向释放函数提供长度的情况下释放它们,这将是非常有限的,因此常规释放函数也需要长度
你可能会感兴趣C++有一个提供了关于为什么要求应用程序跟踪已分配内存区域的长度而不是堆管理器更可取的更多讨论。如果我们检查Box::from_raw
的类型,我们会看到它从原始*mut u8
构造了一个Box
。我们需要一个*mut[u8]
(指向切片的胖指针)来构造一个框
(这是我们在一开始就有的)
而drop
pingaBox
最多只会释放一个字节的内存(如果不会导致运行时错误的话),而drop
pingaBox
则会正确释放所有内存。不,您要做的是未定义的行为,必须将之间的类型转换为\u raw()
和来自\u raw()
匹配。Rust alloc API不要求分配器记住任何信息,因此分配实现将期望传递给它的所有信息的正确性
在您的示例中,*mut u8
和*mut[u8]
是完全不同的类型,因此具有不同的布局
此外,类型不匹配可能会阻止析构函数正常运行
您不能使用from_raw()
来使用void*
销毁任何像Cfree()
这样的指针。不。为什么您认为要释放的数据量不重要?我对内存管理的理解很弱,但据我所知,在C中可以调用malloc
(带有用于分配内存量的参数),返回指针,然后稍后对该指针调用free
(不传入指定要释放多少内存的参数).malloc API自己处理大小,rust alloc API让用户处理大小信息,这通常可以避免重复信息,但更依赖用户。(但rust的普通用户通常不需要知道这一点)