Last active
December 29, 2022 22:40
-
-
Save ruxo/d8e83ab0e54ef9100877a404590f7133 to your computer and use it in GitHub Desktop.
Fixed address solution for Rust 1.66
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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