【小测试】rust中的数组越界——好吧,这下证明rust不是零成本抽象了吧
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
1.编译期发现的数组越界
在数组下标是常量的情况下,编译期就会发现。
- cargo new arr_test
- 在arr_test/src/main.rs中写入:
fn main() {
let mut arr : [i64;10] = [0,1,2,3,4,5,6,7,8,9];
println!("{:?}",arr[10]);
}
- 执行cargo run
- 编译器错误信息为:
error: this operation will panic at runtime
--> src/main.rs:10:21
|
3 | println!("{:?}",arr[10]);
| ^^^^^^^ index out of bounds: the length is 10 but the index is 10
|
= note: `#[deny(unconditional_panic)]` on by default
warning: `arr_test` (bin "arr_test") generated 1 warning
error: could not compile `arr_test` due to previous error; 1 warning emitted
2.运行期的数组越界
- main.rs的内容为:
use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
let mut arr : [i64;10] = [0,1,2,3,4,5,6,7,8,9];
let start = SystemTime::now();
let since_the_epoch = start
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
let ts = since_the_epoch.as_secs() as usize;
let idx = ts % 10; //下标的数据类型必须是usize
println!("{:?}", arr[idx+9]); //90%的概率会越界
}
- cargo run:
thread 'main' panicked at 'index out of bounds: the len is 10 but the index is 13', src/main.rs:19:22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
由此说明: rust加上了运行期的越界检查,以此避免异常的行为。
那么,release版本也会做越界检查吗?
- cargo build --release
- ./arr_test/target/release/arr_test
发现即便是release版本,也是有越界检查的。
由此证明:rust并非零成本抽象,为了做越界检查,编译器一定会在每次访问数组下标的时候加上两条越界检查指令。
3.跳过越界检查
- 直接加上unsafe并不行:
fn main(){
//...
unsafe {
println!("{:?}", arr[idx+9]);
}
}
编译器报错:
warning: unnecessary `unsafe` block
--> src/main.rs:20:5
|
20 | unsafe {
| ^^^^^^ unnecessary `unsafe` block
|
= note: `#[warn(unused_unsafe)]` on by default
只有用上裸指针,rust才认为是unsafe:
use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
let mut arr : [i64;10] = [0,1,2,3,4,5,6,7,8,9];
let start = SystemTime::now();
let since_the_epoch = start
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
let ts = since_the_epoch.as_secs() as usize;
let idx = ts % 10; //下标的数据类型必须是usize
unsafe {
let ref1_at_0 = &mut arr[0];
let ptr2_at_0 = ref1_at_0 as *mut i64;
let ptr3_at_1 = ptr2_at_0.add(idx+9);
println!("{:?}", *ptr3_at_1);
}
}
上面的代码果然成功越界,没有触发panic,打印了一个随机的整形值。
因此:
- 假设用rust数组写一个什么local cache的服务,则每次下标访问必然导致额外的越界检查的开销;
- 避免这种开销的办法就是在unsafe代码中使用裸指针
have fun
【小测试】rust中的数组越界——好吧,这下证明rust不是零成本抽象了吧的更多相关文章
- Java中的数组越界问题
Java中数组初始化和OC其实是一样的,分为动态初始化和静态初始化, 动态初始化:指定长度,由系统给出初始化值 静态初始化:给出初始化值,由系统给出长度 在我们使用数组时最容易出现的就是数组越界问题, ...
- C++中的数组越界
C++中数组发生越界错误时, compiling过程不会报错, linking过程也不会报错, 会在executing过程中发生意想不到的错误或问题.
- Objc中处理数组越界的一种办法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Objc的数组如果在访问时索引非法,则会抛出NSRangeEx ...
- 刷完欧拉计划中难度系数为5%的所有63道题,我学会了Rust中的哪些知识点?
我为什么学Rust? 2019年6月18日,Facebook发布了数字货币Libra的技术白皮书,我也第一时间体验了一下它的智能合约编程语言MOVE,发现这个MOVE是用Rust编写的,看来想准确理解 ...
- Rust中的Slices
这个slice切片,python中有,go中有, 但确实,Rust中最严格. 精彩见如下URL: Rust 程序设计语言(第二版) 简体中文版 · GitBook (Legacy) https://k ...
- 【译】理解Rust中的Futures (一)
原文标题:Understanding Futures In Rust -- Part 1 原文链接:https://www.viget.com/articles/understanding-futur ...
- Rust中的宏:声明宏和过程宏
Rust中的声明宏和过程宏 宏是Rust语言中的一个重要特性,它允许开发人员编写可重用的代码,以便在编译时扩展和生成新的代码.宏可以帮助开发人员减少重复代码,并提高代码的可读性和可维护性.Rust中有 ...
- PHP中使用PDO操作事务的一些小测试
关于事务的问题,我们就不多解释了,以后在学习 MySQL 的相关内容时再深入的了解.今天我们主要是对 PDO 中操作事务的一些小测试,或许能发现一些比较好玩的内容. 在 MyISAM 上使用事务会怎么 ...
- java中的数组 和 封装
package com.aaa.zxf; /** * 一. 普通java项目 导入测试类的方法. * ideal 中 java 项目中导入测试类的方法 手动写入 * import org.junit. ...
- iOS如何彻底避免数组越界
我们先来看看有可能会出现的数组越界Crash的地方: ? 1 2 3 4 5 6 7 - (void)tableView:(UITableView *)tableView didSelectRowAt ...
随机推荐
- 如何在 Unity 游戏中集成 AI 语音识别?
简介 语音识别是一项将语音转换为文本的技术,想象一下它如何在游戏中发挥作用?发出命令操纵控制面板或者游戏角色.直接与 NPC 对话.提升交互性等等,都有可能.本文将介绍如何使用 Hugging Fac ...
- Bert不完全手册4. 绕开BERT的MASK策略?XLNET & ELECTRA
基于随机token MASK是Bert能实现双向上下文信息编码的核心.但是MASK策略本身存在一些问题 MASK的不一致性:MASK只在预训练任务中存在,在微调中不存在,Bert只是通过替换部分的随机 ...
- CF:706B. Interesting drink (二分查找)
题意:不同奶茶店里同样的奶茶价格不同,问在当天Yuki持有的零钱能在几家店购买 思路:对价格数组排序,先优先判断是否会比较最大值和最小值,然后二分查找 #include<bits/stdc++. ...
- JSP | Tomcat目录结构详解
前排提醒:本文不涉及如何安装 Tomcat,仅分析Tomcat目录结构. Tomcat 版本:apache-tomcat-8.5.71 Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器 ...
- xapian 搜索引擎介绍与使用入门
Xapian 是一个开源搜索引擎库,使用 C++ 编写,并提供绑定(bindings )以允许从多种编程语言使用.它是一个高度适应性的工具包,允许开发人员轻松地将高级索引和搜索功能添加到自己的应用程序 ...
- 正泰电力携手图扑:VR 变电站事故追忆反演
VR(Virtual Reality,虚拟现实)技术作为近年来快速发展的一项新技术,具有广泛的应用前景,支持融合人工智能.机器学习.大数据等技术,实现更加智能化.个性化的应用.在电力能源领域,VR 技 ...
- SpringCloud学习 系列十、服务熔断与降级(1-简介)
系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...
- 深度学习基础课:“判断性别”Demo需求分析和初步设计(上)
大家好~我开设了"深度学习基础班"的线上课程,带领同学从0开始学习全连接和卷积神经网络,进行数学推导,并且实现可以运行的Demo程序 线上课程资料: 本节课录像回放 扫码加QQ群, ...
- LaTeX 公式识别问题
问题 想要方便的图片公式识别工具来写Latex(论文)/markdown(笔记)文件 工具推荐 1.mathpix 识别成功率最高(无论是多行,表格表现都非常良好),最好用的工具,但是收费高且付费麻烦 ...
- C++初始化列表时,形参和实参名可以一样,编译器可以识别
在这里初始化列表直接用age(age)即可,用this->age(age)反而会出错,C++不允许在成员初始化列表中使用this关键字来初始化类成员 class Person { public: ...
