我正在尝试在Rust中调用C函数,我遇到了一个奇怪的问题。此代码重现了我的问题:
C
int t(uint8_t *data){
*data = 1;
*(data+1) = 2;
*(data+2) = 3;
}
// block1
unsafe {
let data = Vec::with_capacity(1024).as_mut_ptr();
t(data);
println!("{:?}", Vec::from_raw_parts(data, 4, 4));
}
// block2
unsafe {
let mut data: Vec<u8> = Vec::with_capacity(1024);
let pdata = data.as_mut_ptr();
t(pdata);
println!("{:?}", Vec::from_raw_parts(pdata, 4, 4));
}
我希望输出为[1, 2, 3, 0]
。
只有“block2”有效,“block1”输出[91, 57, 49, 44]
。我不知道它来自哪里。
最令人困惑的是,当我将“block1”放在“block2”之后并将它们一起运行时,它们都正确输出[1, 2, 3, 0]
。
我没注意到什么?两个街区之间有什么区别?
答案 0 :(得分:1)
我相信这里发生的事情是
let data = Vec::with_capacity(1024).as_mut_ptr();
这最终会产生未定义的行为。这里,Vec<T>
是临时的,因此在此行运行后将释放其内存,因此您将传入一个指向C的错误指针。
当你移动代码时你会得到不同的结果似乎也意味着UB在这里。