-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunsafe_usage.rs
More file actions
143 lines (111 loc) · 2.92 KB
/
Copy pathunsafe_usage.rs
File metadata and controls
143 lines (111 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use core::slice;
use std::{slice::from_raw_parts, str::from_utf8_unchecked};
/// 裸指针
/// 两种形式:
/// 1. *const T:不可变
/// 2. *mut T:可变
/// 用途一:解引用裸指针
pub fn raw_pointer() {
let num = 5;
let p = &num as *const i32;
println!("{:?}", p);
// 对一个裸指针解引用需要在 unsafe 块下
unsafe {
println!("{}", *p);
}
}
// 数组指针
pub fn vec_pointer() {
let vs = vec![1, 2, 3];
let mut p = &vs[0] as *const i32;
println!("{:?}", p);
unsafe {
p = p.wrapping_add(1);
println!("{:?}", p);
println!("{}", *p);
p = p.add(1);
println!("{:?}", p);
println!("{}", *p);
}
}
/// 基于引用创建裸指针
/// 创建裸指针是安全行为
pub fn create_raw_pointer() {
let num = 5;
let p1 = &num as *const i32;
let p2 = &num as *const i32;
println!("p1: {:?}", p1);
println!("p2: {:?}", p2);
}
/// 基于内存地址创建裸指针
pub fn create_raw_pointer_from_address() {
let address = 0x12345_usize;
let p = address as *const i32;
println!("{:?}", p);
// unsafe {
// println!("{}", *p);
// }
}
pub fn use_raw_pointer_from_address() {
fn get_location_of_str() -> (usize, usize) {
let s = "hello world";
(s.as_ptr() as usize, s.len())
}
fn print_str(pointer: usize, length: usize) -> &'static str {
unsafe { from_utf8_unchecked(from_raw_parts(pointer as *const u8, length)) }
}
let (pointer, length) = get_location_of_str();
println!(
"get_location_of_str & print_str: {}",
print_str(pointer, length)
);
}
/// 基于智能指针创建裸指针
pub fn create_raw_pointer_from_box() {
let a: Box<i32> = Box::new(3);
let b = &*a as *const i32;
let c: *const i32 = &*a;
println!("create raw pointer from box {:?}, {:?}", b, c)
}
pub fn test_split_at_mut() {
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
let len = slice.len();
let ptr = slice.as_mut_ptr();
unsafe {
(
slice::from_raw_parts_mut(ptr, mid),
slice::from_raw_parts_mut(ptr.add(mid), len - mid),
)
}
}
let mut v = vec![1, 2, 3, 4, 5, 6];
let (part1, part2) = split_at_mut(&mut v, 2);
println!("part1: {:?}, part2: {:?}", part1, part2);
}
// extern "C" {
// fn abc(input: i32) -> i32;
// }
// pub fn test_ffi_abc() {
// unsafe {
// println!("C abc: {}", abc(-2));
// }
// }
/// 实现 unsafe 特性
unsafe trait Fly {
fn use_raw_pointer(&self);
}
struct Foo {
v: i32,
}
unsafe impl Fly for Foo {
fn use_raw_pointer(&self) {
let ptr = &self.v as *const i32;
unsafe {
println!("use_raw_pointer: {}", *ptr);
}
}
}
pub fn unsafe_trait_use_raw_pointer() {
let foo = Foo { v: 5 };
foo.use_raw_pointer();
}