capypad
0 Tage Serie
rust / intermediate
Snippet

Unsafe Rohe Zeiger und MaybeUninit

Unsafe Rust gewährt direkten Speicherzugriff über das hinaus, was sicheres Rust erlaubt. Rohe Zeiger (*const T, *mut T) können nur in unsafe Blöcken dereferenziert werden, was Risiken von undefiniertem Verhalten anerkennt. MaybeUninit<T> ist essentiell um potentiell nicht initialisierten Speicher darzustellen—es führt nicht den Destruktor von T aus und nimmt keinen gültigen Wert an. Dieses Pattern ist entscheidend für FFI-Grenzen, benutzerdefinierte Allocatoren und performance-kritischen Code, der Zero-Initialisierung Overhead vermeiden muss. Stellen Sie immer sicher, dass MaybeUninit Daten vor dem Lesen korrekt initialisiert sind.

snippet.rs
rust
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
use std::mem::MaybeUninit;
use std::ptr;
 
fn demo_raw_pointer() {
let mut value: i32 = 42;
let ptr = &mut value as *mut i32;
unsafe {
println!("Original: {}", *ptr);
*ptr = 100;
println!("Modified: {}", *ptr);
}
}
 
fn demo_maybe_uninit() {
const SIZE: usize = 5;
let mut buffer = [MaybeUninit::<u64>::uninit(); SIZE];
for i in 0..SIZE {
buffer[i] = MaybeUninit::new((i as u64) * 10);
}
let values = unsafe { ptr::read(buffer.as_ptr() as *const [u64; SIZE]) };
println!("Buffer: {:?}", values);
}
 
fn main() {
demo_raw_pointer();
demo_maybe_uninit();
}
Erklärung
1
let ptr = &mut value as *mut i32
Erstellt rohen veränderlichen Zeiger—keine Lifetime angehängt, nur Speicheradresse
2
unsafe { *ptr = 100; }
Unsafe Block anerkennt dass Dereferenzierung roher Zeiger Verantwortung des Aufrufers ist
3
let mut buffer = [MaybeUninit::<u64>::uninit(); SIZE]
MaybeUninit Array—Werte sind nicht initialisiert, kein Drop aufgerufen