pub fn ownership_prevents_uaf() {
let data = Box::new(42); let value = *data;
drop(data);
println!("Copied value: {}", value); }
pub fn lifetime_prevents_dangling_ref() {
let _reference: Option<&String> = None;
{
let _data = String::from("temporary");
}
}
pub fn borrowing_prevents_uaf() {
let mut data = vec![1, 2, 3];
let reference = &data[0];
println!("First element: {}", reference);
data.clear(); println!("Vector cleared");
}
use std::rc::Rc;
pub fn shared_ownership_safe() {
let data = Rc::new(vec![1, 2, 3]);
let clone1 = Rc::clone(&data);
let clone2 = Rc::clone(&data);
println!("Data from clone1: {:?}", clone1);
println!("Data from clone2: {:?}", clone2);
drop(clone1);
drop(clone2);
drop(data); }
pub struct SafeObject {
data: Vec<i32>,
}
impl SafeObject {
pub fn new(data: Vec<i32>) -> Self {
Self { data }
}
pub fn get_data(&self) -> &[i32] {
&self.data
}
pub fn consume(self) -> Vec<i32> {
self.data
}
}
pub fn safe_object_usage() {
let obj = SafeObject::new(vec![1, 2, 3]);
let data_ref = obj.get_data();
println!("Data: {:?}", data_ref);
let owned_data = obj.consume();
println!("Owned data: {:?}", owned_data);
}
pub fn compile_time_safety_demo() {
struct Resource {
id: i32,
}
impl Drop for Resource {
fn drop(&mut self) {
println!("Resource {} freed", self.id);
}
}
let res = Resource { id: 1 };
println!("Resource created: {}", res.id);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ownership_transfer() {
let data = Box::new(42);
let moved_data = data;
assert_eq!(*moved_data, 42);
}
#[test]
fn test_reference_lifetime() {
let data = String::from("test");
let reference = &data;
assert_eq!(reference, "test");
}
#[test]
fn test_rc_shared_ownership() {
let data = Rc::new(vec![1, 2, 3]);
let clone = Rc::clone(&data);
assert_eq!(Rc::strong_count(&data), 2);
drop(clone);
assert_eq!(Rc::strong_count(&data), 1);
}
#[test]
fn test_safe_object() {
let obj = SafeObject::new(vec![1, 2, 3]);
assert_eq!(obj.get_data(), &[1, 2, 3]);
let data = obj.consume();
assert_eq!(data, vec![1, 2, 3]);
}
}