Playing with unsafe can be quite fun.
Last active
May 13, 2017 07:52
-
-
Save gregtatum/51fadd788565c2cf5ca84a832a2e2e8c to your computer and use it in GitHub Desktop.
Rust doodles
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
fn main() { | |
let my_box: Box<[i32]> = Box::new([10, 40, 30]); | |
let pointer_to_box = Box::into_raw(my_box); | |
let my_box: Box<[i32]> = unsafe { Box::from_raw(pointer_to_box) }; | |
println!(" | |
Boxes are pointers to something allocated on the heap. | |
Heap location: {:?} | |
Heap contents: {:?} | |
", | |
pointer_to_box, | |
my_box | |
); | |
let vec = my_box.into_vec(); | |
println!(" | |
Here is the same Box heap allocation of an array, converted over to a Vector | |
Capacity: {:?} | |
Length: {:?} | |
Heap location: {:?} | |
Vector: {:?} | |
", | |
vec.capacity(), | |
vec.len(), | |
vec.as_ptr(), | |
vec | |
); | |
} | |
/* | |
Boxes are pointers to something allocated on the heap. | |
Heap location: 0x10b420000 | |
Heap contents: [10, 40, 30] | |
Here is the same Box heap allocation of an array, converted over to a Vector | |
Capacity: 3 | |
Length: 3 | |
Heap location: 0x10b420000 | |
Vector: [10, 40, 30] | |
*/ |
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
extern crate rand; | |
use std::mem; | |
struct ByteBuf<'a> (&'a [u8], i32); | |
impl<'a> std::fmt::LowerHex for ByteBuf<'a> { | |
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { | |
let mut i = 0; | |
for byte in self.0 { | |
if i % self.1 == 0 { | |
fmtr.write_fmt(format_args!("| ")); | |
} | |
try!( fmtr.write_fmt(format_args!("{:02x} ", byte))); | |
i += 1; | |
} | |
Ok(()) | |
} | |
} | |
fn output_size<T>(name: &'static str, value: &T) { | |
let size = mem::size_of_val(value); | |
println!("-----------------------------------------------------------------------------------------"); | |
println!("{} ( {} bytes, {} bits, {} words )", | |
name, | |
size, | |
8 * size, | |
size as f64 / mem::size_of::<usize>() as f64 | |
); | |
} | |
struct MyStruct { | |
a: i32, | |
b: i32 | |
} | |
fn main() { | |
let array: [i32; 4] = [0x11111111, 0x22222222, 0x33333333, 0x44444444]; | |
let slice: &[i32] = &array[..]; | |
let mut vector: Vec<i32> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
vector.push(0); | |
let my_box: Box<[i32; 4]> = Box::new([0x11111111, 0x22222222, 0x33333333, 0x44444444]); | |
let fat_box: Box<[i32]> = (vec![0x11111111, 0x22222222, 0x33333333]).into_boxed_slice(); | |
let my_struct = MyStruct {a: 0x11111111, b: 0x22222222}; | |
unsafe { | |
output_size("array ", &array); // | i32 | i32 | i32 | i32 | | |
let array_stack: [u8; 16] = mem::transmute_copy(&array); | |
println!("(stack) | i32 | i32 | i32 | i32 |"); | |
println!(" {:x}|\n", ByteBuf(&array_stack, 4)); | |
output_size("slice ", &slice); // | pointer | length | | |
let slice_values: [u8; 16] = mem::transmute_copy(&slice); | |
println!("(stack) | pointer | length |"); | |
println!(" {:x}|\n", ByteBuf(&slice_values, 8)); | |
output_size("vector ", &vector); // | pointer | capacity | length | | |
let vector_values: [u8; 24] = mem::transmute_copy(&vector); | |
println!("(stack) | pointer | capacity | length |"); | |
println!(" {:x}|\n", ByteBuf(&vector_values, 8)); | |
output_size("my_box ", &my_box); // | |
let my_box_values: [u8; 8] = mem::transmute_copy(&my_box); | |
println!("(stack) | pointer |"); | |
println!(" {:x}|\n", ByteBuf(&my_box_values, 8)); | |
output_size("*my_box ", &*my_box); | |
let inside_my_box_values: [u8; 16] = mem::transmute_copy(&*my_box); | |
println!("(heap) | i32 | i32 | i32 | i32 |"); | |
println!(" {:x}|\n", ByteBuf(&inside_my_box_values, 4)); | |
output_size("fat_box ", &fat_box); | |
let fat_box_values: [u8; 16] = mem::transmute_copy(&fat_box); | |
println!("(stack) | pointer | length |"); | |
println!(" {:x}|\n", ByteBuf(&fat_box_values, 8)); | |
output_size("my_struct", &my_struct); | |
let my_struct_values: [u8; 8] = mem::transmute_copy(&my_struct); | |
println!("(stack) | i32 | i32 |"); | |
println!(" {:x}|\n", ByteBuf(&my_struct_values, 4)); | |
} | |
} | |
/* | |
----------------------------------------------------------------------------------------- | |
array ( 16 bytes, 128 bits, 2 words ) | |
(stack) | i32 | i32 | i32 | i32 | | |
| 11 11 11 11 | 22 22 22 22 | 33 33 33 33 | 44 44 44 44 | | |
----------------------------------------------------------------------------------------- | |
slice ( 16 bytes, 128 bits, 2 words ) | |
(stack) | pointer | length | | |
| 88 bd 7c 52 ff 7f 00 00 | 04 00 00 00 00 00 00 00 | | |
----------------------------------------------------------------------------------------- | |
vector ( 24 bytes, 192 bits, 3 words ) | |
(stack) | pointer | capacity | length | | |
| 50 b0 81 0d 01 00 00 00 | 12 00 00 00 00 00 00 00 | 0a 00 00 00 00 00 00 00 | | |
----------------------------------------------------------------------------------------- | |
my_box ( 8 bytes, 64 bits, 1 words ) | |
(stack) | pointer | | |
| 00 00 82 0d 01 00 00 00 | | |
----------------------------------------------------------------------------------------- | |
*my_box ( 16 bytes, 128 bits, 2 words ) | |
(heap) | i32 | i32 | i32 | i32 | | |
| 11 11 11 11 | 22 22 22 22 | 33 33 33 33 | 44 44 44 44 | | |
----------------------------------------------------------------------------------------- | |
fat_box ( 16 bytes, 128 bits, 2 words ) | |
(stack) | pointer | length | | |
| 10 00 82 0d 01 00 00 00 | 03 00 00 00 00 00 00 00 | | |
----------------------------------------------------------------------------------------- | |
my_struct ( 8 bytes, 64 bits, 1 words ) | |
(stack) | i32 | i32 | | |
| 11 11 11 11 | 22 22 22 22 | | |
*/ |
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
fn main() { | |
let mut vec = vec![2i32, 3, 4]; | |
let mut ptr = vec.as_mut_ptr(); | |
unsafe { | |
let my_box = Box::from_raw(ptr); | |
// At this point the box doesn't know what it points to, there is no sizing information, | |
// it is lost when we naively use a pointer to a Vec's data. | |
println!("my_box: {:?}", my_box) | |
// > my_box: 2 | |
} | |
let mut vec = vec![2i32, 3, 4]; | |
let mut ptr = vec.as_mut_ptr(); // The type is inferred as *mut i32 | |
unsafe { | |
// Cast the pointer into the appropriate type. | |
let my_box = Box::from_raw(ptr as *mut [i32; 3]); | |
// Now the box knows what it points to, there is nothing in memory that records the size | |
// information, it's only known at compile time. | |
println!("my_box: {:?}", my_box) | |
// > my_box: [2, 3, 4] | |
} | |
} |
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
extern crate rand; | |
fn main() { | |
let mut vec = vec![2i32, 3, 4]; | |
for i in 0..rand::random::<u8>() { | |
vec.push(i as i32); | |
} | |
let my_box = vec.into_boxed_slice(); | |
let pointer_to_box = Box::into_raw(my_box); | |
let my_box = unsafe { Box::from_raw(pointer_to_box) }; | |
println!(" | |
Boxes are pointers to something allocated on the heap. | |
Heap location: {:?} | |
Heap contents: {:?} | |
", | |
pointer_to_box, | |
my_box | |
); | |
} |
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
fn main() { | |
let vec = vec![0.0, 1.0]; | |
println!( | |
" | |
Rust Vectors store this information on the stack: | |
Capacity: {:?} | |
Length: {:?} | |
Memory location: {:?} | |
", | |
vec.capacity(), | |
vec.len(), | |
vec.as_ptr() | |
); | |
} | |
/* | |
Rust Vectors store this information on the stack: | |
Capacity: 2 | |
Length: 2 | |
Memory location: 0x108620000 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment