عدم ارجاع به اشارهگرهای خام
ایجاد اشارهگر ایمن است، اما عدم ارجاع به آنها «ناامن» یا unsafe
است:
fn main() { let mut s = String::from("مراقب باش!"); let r1 = &mut s as *mut String; let r2 = r1 as *const String; // SAFETY: 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 برابر هست: {}", *r1); *r1 = String::from("اوهو"); println!("r2 برابر هست: {}", *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.
این تمرین خوبی است (و طبق راهنمای سبک Android Rust لازم است) برای هر بلوک unsafe
یک نظر بنویسید و توضیح دهد که چگونه کد داخل آن الزامات ایمنی عملیات ناامنی را که انجام میدهد برآورده میکند.
در مورد عدم ارجاع اشارهگر، این بدان معنی است که نشانگرها باید valid باشند، یعنی:
- اشارهگر باید غیر تهی یا non-null باشد.
- اشارهگر باید dereferenceable باشد (در محدوده یک object اختصاص داده شده).
- این object نباید جابجا شده باشد.
- دسترسی همزمان به یک مکان نباید وجود داشته باشد.
- اگر اشارهگر با فرستادن یک reference به دست آمده باشد، object زیرین باید live باشد و نمیتوان از هیچ مرجعی برای دسترسی به حافظه استفاده کرد.
در بیشتر موارد، اشارهگر نیز باید به درستی تراز شود.
بخش «NOT SAFE» نمونهای از یک نوع رایج از اشکال UB را ارائه میکند: *r1
دارای طول عمر 'static
است، بنابراین r3
دارای نوع &'static String
است و بنابراین عمر s
بیشتر میشود. ایجاد یک مرجع از یک اشاره گر نیاز به دقت بسیار دارد.