如何防止Rust程序释放(释放)它不拥有的C字节
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止Rust程序释放(释放)它不拥有的C字节相关的知识,希望对你有一定的参考价值。
libc有一个函数,该函数返回不应为free()d的字符串。可以从/etc/passwd
读取用户的当前目录,但不应将其为free()d。如果我从指针创建字符串,程序将异常终止
free(): invalid pointer
Aborted (core dumped)
显然该代码不安全。
let pw = libc::getpwnam(username.as_ptr() as *const i8);
let cd = (*pw).pw_dir;
let len = libc::strlen(cd);
builder.current_dir(String::from_raw_parts(cd as *mut u8, len, len));
我可以mem::forget(s)
字符串,但是会泄漏内存,至少必须将长度存储在某个位置。我只需要防止释放基础原始字节。项目是一台服务器,所以我不能忽略泄漏。
String::from_raw_parts
是在此处使用的错误功能。该函数只能用先前从String::from_raw_parts
或同等方法获得的指针来调用,这显然在您的代码中不是这种情况,因为该字符串来自C库,甚至没有动态分配。
相反,应该使用String::into_raw_parts
和&str
或为此目的设计的slice::from_raw_parts
类型创建指向数据的slice::from_raw_parts
。拥有str::from_utf8
后,应将其复制到一个拥有的字符串中,然后使用该字符串调用str::from_utf8
。用CStr
调用CStr
会编译,但是不安全,需要您证明该函数(及其调用的函数)从不调用&str
。
这里是一个例子:
builder.current_dir()
请注意,此代码实际上也不安全,因为它不能在多个线程中使用。您应该改用builder.current_dir()
,或者更好的是,使用像&str
那样的板条箱代替getpwnam
。
以上是关于如何防止Rust程序释放(释放)它不拥有的C字节的主要内容,如果未能解决你的问题,请参考以下文章
boost interprocess file_lock 无法锁定它不拥有的文件
在函数中定义数组:float fltNum[10],该数组在内存中是如何被分配内存空间?何时被释放内存空间?c语言中