为什么我的所有指针指向与锈中的to_c_str()相同的位置?

时间:2014-04-14 06:32:05

标签: rust

我有这种生锈方法:

/* Define a python method on a given module */
pub fn method(data: *mut Struct_ppyData, module: ~str, method: ~str, callback: PyCFunction, flags: Method, help: ~str) {
  let mbytes = module.to_c_str().with_mut_ref(|a: * mut c_char| { a });
  let fbytes = method.to_c_str().with_mut_ref(|b: * mut c_char| { b });
  let dbytes = help.to_c_str().with_mut_ref(|c: * mut c_char| { c });
  println!("Incoming! {} {} {}\n", module, method, help);
  println!("Invoking! {} {} {}\n", mbytes, fbytes, dbytes);
  let cflags = flags as c_int;
  unsafe {
    ppy_method(data, mbytes, fbytes, callback, cflags, dbytes);
  }
}

我得到的输出是:

Incoming! yyy xxx A callback.
Invoking! 0x7f85084077d0 0x7f85084077d0 0x7f85084077d0

什么?这也是ffi c调用的内容:

Received a value
Pointer: 7f85084077d0
length: 11
 --------> value: A callback.
Received a value
Pointer: 7f85084077d0
length: 11
 --------> value: A callback.
Received a value
Pointer: 7f85084077d0
length: 11
 --------> value: A callback.

为什么地球上的mbytes,fbytes和dbytes的值都是一样的? O_O

1 个答案:

答案 0 :(得分:2)

你正在做的事情是不安全的,它正在绊倒你。

module.to_c_str()CString分配空间。在with_mut_ref上调用*T会向*mut T提供不安全的指针(CString*mut c_char) - 但CString 仅对关闭时有效你传入。你已经让它在关闭结束后保持活力,因此所有的赌注都已关闭;实际上,*T在表达式之后立即被释放,因为它不存储在任何地方。因此,你有一个悬空的不安全指针(&str被称为不安全的原因!)。然后,下一行进行类似的分配和lo!它在同一个地方。最终结果:三个相同的指针,都指向相同的垃圾数据。

如果你确实需要这样一个不安全的指针,那么你应该做的就是嵌套东西。

此外,正如dbaupp所观察到的,您不需要取得字符串的所有权;您也可以使用~str代替/// Define a python method on a given module pub fn method(data: *mut Struct_ppyData, module: &str, method: &str, callback: PyCFunction, flags: Method, help: &str) { module.to_c_str().with_mut_ref(|mbytes| { method.to_c_str().with_mut_ref(|fbytes| { help.to_c_str().with_mut_ref(|dbytes| { println!("Incoming! {} {} {}\n", module, method, help); println!("Invoking! {} {} {}\n", mbytes, fbytes, dbytes); let cflags = flags as c_int; unsafe { ppy_method(data, mbytes, fbytes, callback, cflags, dbytes); } }) }) }) }

{{1}}