我正在为 libsvm 编写 FFI 包装器。它使用的结构之一有一个 **struct{int, double}
作为成员。其具体规范并不重要,但它基本上只是一个 double 稀疏向量列表。
在我的包装器中,显然我允许数据从 Rust 端进入,所以我有:
#[repr(C)]
pub struct SvmNode(pub i32, pub f64);
#[repr(C)]
struct CSvmProb {
data: *mut *mut SvmNode
// other fields that aren't important
}
pub struct SvmProb {
crep: CSvmProb,
data: Vec<Vec<SvmNode>>,
// other fields that aren't important
raw_data: Vec<*mut SvmNode>
}
extern "C" fn do_something(prob: *mut CSvmProb);
作为引用,这些东西的 C 版本看起来像:
struct svm_node {
int index;
double value;
};
struct svm_prob {
struct svm_node **data;
// other fields that aren't important to the question
};
void do_something(svm_prob *prob);
data
成员在 Rust 端是只读的,它仅用于在构建问题后查找内容。
SvmProb
的crep
的data
字段实际上就是raw_data.as_ptr()
。它的构造方式是从 data
的每个元素中获取 as_mut_ptr
:
impl SvmProb {
pub fn new(mut data: Vec<Vec<SvmNode>>) -> SvmProb {
let raw_data = Vec::with_capacity(data.len());
for v in data.iter_mut() {
raw_data.push(v.as_mut_ptr());
}
// ...
let crep = CSvmProb{ data: raw_data.as_ptr() };
SvmProb { data: data, crep: crep }
}
}
问题是,在 SvmProb
构造之后,raw_data
永远不会被访问或设置,raw_data
指针被添加到 crep
在 SvmProb 被构造并由新函数产生之前。所以 rustc/Cargo 提示 SvmProb
的成员 raw_data
是“死代码”。
我的问题是:这真的是死代码,还是我需要维护 raw_data
以使内存像我想的那样保持活力?或者,有没有办法强制 Vec
产生其原始指针并告诉它在 drop
ped 时不再需要管理它?或者,有没有办法不用 #[allow(dead_code)]
来提示 Rust Vec 存在的唯一原因是为了内存保持事件目的?
我意识到我可以通过使用heap::allocate
和各种其他不安全的访问器来填充CSvmNode.data
,但我觉得使用 Vec 来管理它然后获取它的指针更安全且更不容易出错。
最佳答案
My question is: is this really dead code, or do I need to maintain raw_data for the memory to stay alive like I think I do?
是的,你需要维护raw_data
,否则crep
会失效。
您绝对需要 SvmProb
中的 crep
字段吗?相反,我建议您添加一个如下所示的 crep()
方法:
impl SvmProb {
#[inline]
fn crep(&mut self) -> CSvmProb {
CSvmProb { data: self.raw_data.as_mut_ptr() }
}
}
如果您需要更多数据以这种方式初始化CSvmProb
,您需要先将相应的字段添加到SvmProb
。
关于rust - 这个元素 Rust 标记为 "dead code"是必要的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32282995/