Skip to content

Instantly share code, notes, and snippets.

@ruxo
Last active December 29, 2022 22:40
Show Gist options
  • Select an option

  • Save ruxo/d8e83ab0e54ef9100877a404590f7133 to your computer and use it in GitHub Desktop.

Select an option

Save ruxo/d8e83ab0e54ef9100877a404590f7133 to your computer and use it in GitHub Desktop.
Fixed address solution for Rust 1.66
use std::pin::Pin;
use std::ptr::null;
use std::sync::Arc;
#[derive(Clone)]
struct Test {
data: Pin<Arc<[u8; 8]>>,
reference: *const [u8; 8]
}
impl Test {
fn new(x: u8) -> Self {
let mut instance = Self {
data: Arc::pin([x; 8]),
reference: null()
};
instance.reference = Arc::into_raw(Pin::into_inner(instance.data.clone()));
instance
}
fn data_ptr(&self) -> *const [u8; 8] {
Arc::into_raw(Pin::into_inner(self.data.clone()))
}
fn data_mut_ptr(&self) -> *mut [u8; 8] {
self.reference as *mut [u8; 8]
}
}
fn main() {
let a = Test::new(1);
let x = a.reference;
let y = a.data_ptr();
println!("Left = {x:?}, Right = {y:?}");
assert_eq!(x, y);
// Cloning gets same address!
let b = a.clone();
assert_eq!(a.data_ptr(), b.data_ptr());
assert_eq!(b.data_ptr(), b.reference);
let x = b.data_ptr();
let z = a.data_mut_ptr();
unsafe { assert_eq!(*x, [1; 8]); };
let mut expected = [1; 8];
expected[0] = 2;
unsafe {
(*z)[0] = 2;
assert_eq!(*x, expected);
}
// Cloning pinned ARC also gets same address!
let c = Pin::into_inner(a.data.clone());
let mut_c = Arc::into_raw(c);
assert_eq!(mut_c, a.data_mut_ptr());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment