【小测试】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 ...
随机推荐
- Python 可以满足你任何 API 使用需求
摘要:在本教程中学到的概念和技术将允许您使用自己喜欢的任何 API 进行练习,并使用 Python 来满足您可能拥有的任何 API 使用需求. 本文分享自华为云社区<Python 和 API:读 ...
- 使用appuploader工具流程(Windows版本)
转载:使用appuploader工具流程(Windows版本) 目录 转载:使用appuploader工具流程(Windows版本) 一.登录apple官网,注册账号 二.下载Appuploade ...
- OpenSSF发布npm 最佳实践指南,应对开源依赖风险
开源安全基金会(OpenSSF)发布了 npm 最佳实践指南,以帮助 JavaScript 和 TypeScript 开发人员降低使用开源依赖项相关的安全风险.OpenSSF Best Practic ...
- PPT 合并形状
形状格式 -> 插入形状 -> 合并形状 选中的元素,就是要保留的元素. 可以到 https://www.iconfont.cn/ 下载SVG格式插入 PPT中进行使用 合并开状的应用 文 ...
- Nginx--用户认证&&访问控制&&限速&&状态访问
一 用户认证 某些网页只希望给特定的用户访问,可以设置用户认证,使用户访问时需要进行身份认证,只有认证通过才可访问网页 location / { root html; index index.html ...
- OS | 透过 inode 来理解硬链接和软链接
什么是inode? 每个文件都对应一个唯一的inode,inode用来存储文件的元信息,包括: 对应的文件 文件字节数 文件数据块的位置 文件的inode号码 文件的硬链接数 文件的读写权限 文件的时 ...
- UVA - 10391:Compound Words (字符串水题)
题目大意 给定若干单词,按字典序输出由两个单词拼接而成的单词 思路分析 用set存储所有单词,枚举每个单词word,遍历word的所有左右子串组合情况,若左右子串均在set中,说明符合题意.时间复杂度 ...
- L2-012 关于堆的判断 (25分) (字符串處理)
将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: x is the root:x是根结点: x and y are siblings:x和y是兄弟结 ...
- 08.25北京站|阿里云Serverless 技术实践营( AI 专场)开放报名
活动简介 阿里云 Serverless 技术实践营(AI 专场)是一场以聚焦企业级 AIGC 应用开发与落地展开的主题活动,活动受众以关注 Serverless 和 AI 技术的开发者.企业决策人.云 ...
- fetch概述
1.基本特性 更加简单的数据获取方式,功能更强大.更灵活,可以看做是xhr的升级版 基于promise实现 2.语法结构 3.fetch的基本用法
