018 Rust死灵书之非安全方式初始化内存

介绍

本系列录制的视频主要放在B站上Rust死灵书学习视频

Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source

主要内容

安全 Rust 不允许部分地初始化数组,初始化一个数组时,通过let x = [val; N] 为每一个位置赋予相同的值,或者是单独指定每一个成员的值 let x = [val1, val2, val3]。但是有时我们需要用增量或者动态的方式初始化数组。

非安全 Rust 提供了mem::uninitialized处理这一问题。这个函数假装返回一个值,可以用它来欺骗 Rust 我们已经初始化了一个变量了。

特别注意

此方式会带来安全隐患。因为在Rust中,未被初始化的内存,赋值时是将字节拷贝到对应的内存;而对于被初始化过的内存,赋值时除了拷贝外还需要销毁原来的值。

解决方式,通过如下三个函数:

1、ptr::write(ptr, val) 函数接受 val 然后将它的值移入 ptr 指向的地址
2、ptr::copy(src, dest, count) 函数从 src 处将 count 个 T 占用的字节拷贝到 dest。(这个函数和 memmove 相同,不过要注意参数顺序是反的!)
3、ptr::copy_nonoverlapping(src, dest, count) 和 copy 的功能是一样的,不过它假设两段内存不会有重合部分,因此速度会略快一点。(这个函数和 memcpy 相同,不过要注意参数顺序是反的!)

//例子
use std::mem;
use std::ptr;

fn main() {
	// 数组的大小是硬编码的但是可以很方便地修改
	// 不过这表示我们不能用[a, b, c]这种方式初始化数组
	const SIZE: usize = 3;
	
	let mut x: [Box<u32>; SIZE];

	x = [Box::new(1), Box::new(2), Box::new(3)];
	//let y = [Box::new(2), Box::new(3), Box::new(4)];
	x = y;
	
	unsafe {
	    // 欺骗Rust说x已经被初始化
	    x = mem::uninitialized();
		//x = y;//error,调用析构函数,再覆盖,但是x其实没有真正初始化

	    for i in 0..SIZE {
	        ptr::write(&mut x[i], Box::new(i as u32));
	    }
	}
	
	println!("{:?}", x);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值