使用Rust数据修改C函数中的内容会产生未知值

时间:2018-04-08 12:27:07

标签: rust ffi

我正在尝试在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]

我没注意到什么?两个街区之间有什么区别?

1 个答案:

答案 0 :(得分:1)

相信这里发生的事情是

let data = Vec::with_capacity(1024).as_mut_ptr();

这最终会产生未定义的行为。这里,Vec<T>是临时的,因此在此行运行后将释放其内存,因此您将传入一个指向C的错误指针。

当你移动代码时你会得到不同的结果似乎也意味着UB在这里。