线程“主”在“索引超出范围时惊慌:len为2但索引为2”崩溃

时间:2019-09-01 20:00:12

标签: rust

<source>: In function 'main':
<source>:15:5: warning: array subscript 20394 is above array bounds of 'int[4]' [-Warray-bounds]
   15 |     printf( "Result %d\n", cents[ZOD] );
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:7:5: note: while referencing 'cents'
    7 | int cents[] = {
      |     ^~~~~

如果您要使用use std::env; use std::process; fn main(){ let mut repository_urls: Vec<String> = env::args().collect(); if repository_urls.len() == 1 { eprintln!("You have to enter at least one repository url!"); process::exit(1); } else { for i in 0 .. repository_urls.len() - 1 { if repository_urls[i + 1] == "--advanced" && repository_urls.len() >= i + 5 { repository_urls.remove(i + 4); repository_urls.remove(i + 3); repository_urls.remove(i + 2); } else { } } //Ends the process normally process::exit(0); } } 作为参数,它将按预期执行所有操作并执行所有逻辑,但完成后将导致崩溃:

--advanced 1 2 3

我如何获取我的程序,但可以正常退出而不会崩溃?

2 个答案:

答案 0 :(得分:2)

您的直接问题是,您调用remove三次后,循环继续运行。循环范围(0..repository_urls.len() - 1)仅在循环开始时进行评估。但是现在向量长度已更改,然后通过repository_urls[i + 1]访问向量失败。您可以通过在break之后添加remove来解决此问题。

对于命令行参数解析,通常建议使用板条箱。手动执行通常会导致意大利面条式代码和细微的错误。我非常推荐structopt。将它添加到您的应用程序真的很容易。

答案 1 :(得分:0)

在惯用Rust中,@ lukas-kalbertodt的建议通常是在现有向量上创建迭代器,然后使用过滤技术将数据收集到新向量中。请避免从矢量中去除效率很低的