Rust 如何知道我的指针不会被释放?

Rust 如何知道我的指针不会被释放?,rust,Rust,我正在开发一个Linux PAM模块,我实现了这个函数来获取用户 pub fn get_user(pamh:PamHandleT)->PamResultCStr负责处理值,与CString相反,它不分配或取消分配内存,就像str和String一样。您只需向它传递一个指针,并且必须确保它的要求。确保仔细阅读并理解你在做什么 到目前为止,您的代码看起来还不错,所以您应该准备好了。CStr负责处理值,与CString相反,它不分配或取消分配内存,就像str和String一样。您只需向它传递一个指针,并

我正在开发一个Linux PAM模块,我实现了这个函数来获取用户


pub fn get_user(pamh:PamHandleT)->PamResult
CStr
负责处理值,与
CString
相反,它不分配或取消分配内存,就像
str
String
一样。您只需向它传递一个指针,并且必须确保它的要求。确保仔细阅读并理解你在做什么


到目前为止,您的代码看起来还不错,所以您应该准备好了。

CStr
负责处理值,与
CString
相反,它不分配或取消分配内存,就像
str
String
一样。您只需向它传递一个指针,并且必须确保它的要求。确保仔细阅读并理解你在做什么


到目前为止,您的代码看起来还不错,所以您应该准备好开始了。

您可能需要实现自己的价值。不过,这将是一种分配

pub fn get_user(pamh:PamHandleT)->PamResult{
让mut raw_user:*常量c_char=ptr::null();
设r=unsafe{pam_get_user(pamh,&mut raw_user,ptr::null())};
如果原始用户为空(){
错误(r)
}否则{
让用户=不安全{CStr::from_ptr(原始用户)};
Ok(user.to_owned())
}
}
如果要避免分配,应该创建一些上下文对象

“pam_end函数终止pam事务,是应用程序在pam上下文中应调用的最后一个函数。返回后,句柄pamh不再有效,与之相关的所有内存都将无效。”

struct TransactionContext{
pamh:PamHandleT
}
TransactionContext的impl Drop{
fn下降(&mut自我){
不安全{pam_end(pamh);}
}
}
pub fn get_user(pamh:&TransactionContext)->PamResult{
让mut raw_user:*常量c_char=ptr::null();
设r=unsafe{pam_get_user(pamh.pamh,&mut raw_user,ptr::null())};
如果原始用户为空(){
错误(r)
}否则{
让用户=不安全{CStr::from_ptr(原始用户)};
Ok(用户)
}
}

这将使结果CStr具有与TransactionContext相同的生存期,并且借用检查器将确保您在删除TransactionContext后不会使用结果CStr。

您可能需要创建自己的值。不过,这将是一种分配

pub fn get_user(pamh:PamHandleT)->PamResult{
让mut raw_user:*常量c_char=ptr::null();
设r=unsafe{pam_get_user(pamh,&mut raw_user,ptr::null())};
如果原始用户为空(){
错误(r)
}否则{
让用户=不安全{CStr::from_ptr(原始用户)};
Ok(user.to_owned())
}
}
如果要避免分配,应该创建一些上下文对象

“pam_end函数终止pam事务,是应用程序在pam上下文中应调用的最后一个函数。返回后,句柄pamh不再有效,与之相关的所有内存都将无效。”

struct TransactionContext{
pamh:PamHandleT
}
TransactionContext的impl Drop{
fn下降(&mut自我){
不安全{pam_end(pamh);}
}
}
pub fn get_user(pamh:&TransactionContext)->PamResult{
让mut raw_user:*常量c_char=ptr::null();
设r=unsafe{pam_get_user(pamh.pamh,&mut raw_user,ptr::null())};
如果原始用户为空(){
错误(r)
}否则{
让用户=不安全{CStr::from_ptr(原始用户)};
Ok(用户)
}
}

这将使result CStr具有与TransactionContext相同的生存期,并且借用检查器将确保在删除TransactionContext后不使用result CStr。

它现在编译吗?生存期注释不会影响已编译代码的行为。借阅检查器只使用它们来验证代码是否正确,因此它们只确定代码是否编译,而不是它的功能。您的代码似乎很好。但我认为更惯用的方法是创建自己的
用户
包装器,它将保存对
静态CStr的引用。它现在编译了吗?生命周期注释不会影响编译代码的行为。借阅检查器只使用它们来验证代码是否正确,因此它们只确定代码是否编译,而不是它的功能。您的代码似乎很好。但我认为更惯用的方法是创建自己的
用户
包装器,它将包含对
静态CStr的引用,“pam_end函数终止pam事务,是应用程序在pam上下文中应该调用的最后一个函数。返回时,句柄pamh不再有效,与之相关的所有内存都将无效。“。我认为只要句柄有效,它就有效。我不明白你的意思。代码中没有调用
pam\u end
。我的意思是,调用pam\u end可能会使指针无效,因此静态生存期可能不正确。我认为它不正确。”pam_end函数终止pam事务,是应用程序在pam上下文中应该调用的最后一个函数。返回时,句柄pamh不再有效,与之相关的所有内存都将无效。“。我认为只要句柄有效,它就有效。我不明白你的意思。代码中没有调用
pam\u end
。我的意思是,调用pam\u end可能会使指针无效,因此静态生存期可能不正确。
struct TransactionContext{
   pamh: PamHandleT
}

impl Drop for TransactionContext{
  fn drop(&mut self){
     unsafe {pam_end(pamh);}
  }
}

pub fn get_user(pamh: &TransactionContext) -> PamResult<&CStr> {
    let mut raw_user: *const c_char = ptr::null();
    let r = unsafe { pam_get_user(pamh.pamh, &mut raw_user, ptr::null()) };
    if raw_user.is_null() {
        Err(r)
    } else {
        let user = unsafe {CStr::from_ptr(raw_user)};
        Ok(user)
    }
}