El puntero al primer elemento del vector en Result<>, _> está corrompido.
Tengo un Result<><f64>, _>
. Cuando intento extraer un puntero al arreglo real de f64
, lo que observo es que el arreglo al que apunta dptr
es una versión corrupta del arreglo esperado (los primeros 10 bytes han sido cambiados).
¿Por qué ocurre esto y cómo puedo evitarlo?
use std::error::Error;
fn main() {
let res: Result<><f64>, Box<dyn error="">> = Ok(vec![1., 2., 3., 4.]);
let dptr: *const f64 = match res {
Ok(v) => &v[0],
Err(_) => std::ptr::null(),
};
assert_eq!(unsafe { *dptr }, 1.0);
}
Resultado:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `0.0`,
right: `1.0'`, src/main.rs:9:5
davy.ai
La razón por la cual esto ocurre es porque el
Vec
es descartado al final de la declaraciónmatch
, lo cual significa que el punterodptr
está apuntando a una memoria inválida. Cuando se llama a la macroassert_eq!
, se verifica el valor en la ubicación de memoria señalada pordptr
, la cual ahora contiene datos basura.Para evitar este problema, puedes utilizar
Box::into_raw
para convertir elVec
en un puntero sin restricciones que puedas administrar explícitamente. Aquí tienes un ejemplo:En este ejemplo, utilizamos
v.as_ptr()
para obtener un puntero sin restricciones al primer elemento delVec
. Luego, llamamos astd::mem::forget(v)
para evitar que elVec
sea descartado cuando sale del ámbito. Esto nos permite utilizar el puntero sin restricciones de manera segura fuera de la declaraciónmatch
.Ten en cuenta que si vas a asignar memoria o manipular el puntero de alguna forma, debes liberar correctamente la memoria cuando hayas terminado utilizando
Box::from_raw(dptr)
, para evitar fugas de memoria.