在这种情况下,我想从字符串中进行一些数据转换,为了方便起见,我将其转换为中间的指针,现在我想返回字符串的一部分,但是我受此异常困扰:
foo(74363,0x10fd2fdc0) malloc: *** error for object 0x7ff65ff000d1: pointer being freed was not allocated
foo(74363,0x10fd2fdc0) malloc: *** set a breakpoint in malloc_error_break to debug
当我尝试调试程序时,出现了如上所述的错误消息。这是我的示例代码:
fn main() {
unsafe {
let mut s = String::from_utf8_unchecked(vec![97, 98]);
let p = s.as_ptr();
let k = p.add(1);
String::from_raw_parts(k as *mut u8, 1, 1);
}
}
在unsafe
不了解函数文档的情况下,绝对不要使用函数(100%)。
所以,这说明了什么String::from_raw_parts
:
安全
由于未检查的不变量数量,这是非常不安全的:
- 所需的内存
ptr
事先已由标准库使用的同一分配器分配,且要求的对齐方式恰好为1。length
需要小于或等于容量。capacity
必须是正确的值。违反这些规则可能会导致诸如破坏分配器的内部数据结构之类的问题。
将ptr的所有权有效地转移到String,然后可以随意分配,重新分配或更改指针所指向的内存内容。调用此函数后,请确保没有其他人使用指针。
这里有两点很突出:
ptr
需要预先分配了at的内存。capacity
必须是正确的值。这些与Rust中分配的工作方式有关。本质上,释放仅期望分配返回的指针值(和类型)。
不允许尝试使用分配不同的对齐方式或使用不同的大小来尝试释放分配中间的指针。
此外,您还错过了:
在这里,的原始实例String
仍然拥有该分配,并且您尝试从中释放一个字节。它永远不可能顺利。
甚至在此之前,示例代码就开始出错,在其中
String::from_utf8_unchecked(vec![127, 128])
创建了invalidString
。@trentcl:很好,我专心研究内存问题,但还有其他问题。
@trentcl对不起,我忘记了我的错误。