small fix to the tutorial-ffi destructor example
The previous example was erroneously attempting to destroy uninitialized memory, which was often zeroed (masking the bug).
This commit is contained in:
parent
d74ac9ea03
commit
8f2d71ac00
|
@ -150,11 +150,7 @@ wrapping `malloc` and `free`:
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
use core::libc::{c_void, size_t, malloc, free};
|
use core::libc::{c_void, size_t, malloc, free};
|
||||||
|
use core::unstable::intrinsics;
|
||||||
#[abi = "rust-intrinsic"]
|
|
||||||
extern "rust-intrinsic" mod rusti {
|
|
||||||
fn init<T>() -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
// a wrapper around the handle returned by the foreign code
|
// a wrapper around the handle returned by the foreign code
|
||||||
pub struct Unique<T> {
|
pub struct Unique<T> {
|
||||||
|
@ -166,7 +162,8 @@ pub impl<'self, T: Owned> Unique<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = malloc(core::sys::size_of::<T>() as size_t) as *mut T;
|
let ptr = malloc(core::sys::size_of::<T>() as size_t) as *mut T;
|
||||||
assert!(!ptr::is_null(ptr));
|
assert!(!ptr::is_null(ptr));
|
||||||
*ptr = value;
|
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
|
||||||
|
intrinsics::move_val_init(&mut *ptr, value);
|
||||||
Unique{ptr: ptr}
|
Unique{ptr: ptr}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +183,7 @@ pub impl<'self, T: Owned> Unique<T> {
|
||||||
impl<T: Owned> Drop for Unique<T> {
|
impl<T: Owned> Drop for Unique<T> {
|
||||||
fn finalize(&self) {
|
fn finalize(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut x = rusti::init(); // dummy value to swap in
|
let mut x = intrinsics::init(); // dummy value to swap in
|
||||||
x <-> *self.ptr; // moving the object out is needed to call the destructor
|
x <-> *self.ptr; // moving the object out is needed to call the destructor
|
||||||
free(self.ptr as *c_void)
|
free(self.ptr as *c_void)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue