Dereferenciación de Punteros Sin Formato

La creación de punteros es un proceso seguro, pero para anular las referencias, es necesario utilizar unsafe:

fn main() {
    let mut s = String::from("careful!");

    let r1 = &mut s as *mut String;
    let r2 = r1 as *const String;

    // Safe because r1 and r2 were obtained from references and so are
    // guaranteed to be non-null and properly aligned, the objects underlying
    // the references from which they were obtained are live throughout the
    // whole unsafe block, and they are not accessed either through the
    // references or concurrently through any other pointers.
    unsafe {
        println!("r1 is: {}", *r1);
        *r1 = String::from("uhoh");
        println!("r2 is: {}", *r2);
    }

    // NOT SAFE. DO NOT DO THIS.
    /*
    let r3: &String = unsafe { &*r1 };
    drop(s);
    println!("r3 is: {}", *r3);
    */
}
This slide should take about 10 minutes.

Se recomienda (y es obligatorio en la guía de estilo Rust de Android) escribir un comentario para cada bloque unsafe explicando cómo el código que contiene cumple los requisitos de seguridad de las operaciones inseguras que realiza.

En el caso de la desreferenciación de punteros, significa que los punteros deben ser válidos, por ejemplo:

  • El puntero no puede ser nulo.
  • El puntero debe ser desreferenciable (dentro de los límites de un único objeto asignado).
  • El objeto no debe haberse desasignado.
  • No debe haber accesos simultáneos a la misma ubicación.
  • Si el puntero se ha obtenido enviando una referencia, el objeto subyacente debe estar activo y no puede utilizarse ninguna referencia para acceder a la memoria.

En la mayoría de los casos, el puntero también debe estar alineado adecuadamente.

The “NOT SAFE” section gives an example of a common kind of UB bug: *r1 has the 'static lifetime, so r3 has type &'static String, and thus outlives s. Creating a reference from a pointer requires great care.