我怎么能改变一个框结构体的字段值,同时确保指针的盒子保持有效?



我有以下rust代码:

pub struct Settings {
pub vec: Vec<usize>,
pub index: usize,
}
pub fn add_to_settings_vec(ptr: *mut Settings) {
// create a box from the pointer
let boxed_settings = unsafe { Box::from_raw(ptr) };
// get the value in the box
let mut settings = *boxed_settings;
// mutate the value
settings.vec.push(123);
// create a new box and get a raw pointer to it so the value isn't deallocated
Box::into_raw(Box::new(project));
}

我想确保作为函数参数传递的指针保持有效并指向修改后的Settings值,即使在向未装箱的Settings值的向量添加元素之后。

我想我需要以下步骤来实现我的目标:

  • 接收到Settings的指针
  • 打开
  • 修改设置
  • 确保Settings不被释放
  • 现在我需要传入的指针仍然有效,并指向修改后的Settings

这应该是可能的,因为Settings值是固定大小,据我所知,即使是向量,因为向量在不同的位置增长其内存。

我已经看了https://doc.rust-lang.org/std/boxed/struct.Box.html上的文档,但我还没能弄清楚。

我也读过关于大头针,但我不知道如何或何时使用它们:https://doc.rust-lang.org/std/pin/index.html.

上面的代码是否总是保留传入的指针?我希望你能解释一下为什么或为什么不。

如果不是,我怎么能确保传入的指针保持有效,并继续指向修改的Settings值,在内存中的同一位置?

Unbox value
就地修改设置
确保设置不会被取消分配

它已经在步骤(1)中被释放了:当你执行它时,你将Settings结构体移出了Box,并在这样做时释放了Box。

我不明白你为什么要经历这些混乱(或者为什么你把不安全的指针传递给一个安全的非外部函数)。

// create a box from the pointer
let mut settings = unsafe { Box::from_raw(ptr) };
// mutate the value
settings.vec.push(123);
settings.leak();

可以很好地工作,并且不会释放任何东西。虽然它仍然是有风险的,没有必要在Box上得到一个句柄,如果指针只是借来的(这似乎是在这里,因为设置永远不会返回。

一个更好的方法是创建一个借用的设置vec:

let v = unsafe { &mut (*ptr).vec };
v.push(123);

如果还需要更新索引,也可以使用settings结构体:

let settings = unsafe { &mut (*ptr) };
settings.vec.push(123);

您可以通过解引用不安全块中的指针来实现突变:

pub struct Settings {
pub vec: Vec<usize>,
pub index: usize,
}
pub fn add_to_settings_vec(ptr: *mut Settings) {
// mutate the value
unsafe {(*ptr).vec.push(123)};
}
fn main() {
let mut s = Settings {
vec: vec![],
index: 10,
};

add_to_settings_vec(&mut s as *mut Settings);
println!("{:?}", s.vec);
}

游乐场

相关内容

  • 没有找到相关文章

最新更新