SmushyTaco
SmushyTaco

Reputation: 1551

thread 'main' panicked at 'index out of bounds: the len is 2 but the index is 2' crash

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);
    }
}

If you were to have --advanced 1 2 3 for the arguments for this it would do everything and execute all the logic as intended but when it finishes it ends up crashing with:

thread 'main' panicked at 'index out of bounds: the len is 2 but the index is 2', /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c/src/libcore/slice/mod.rs:2695:10
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

How would I get my program but exit normally without a crash?

Upvotes: 2

Views: 9408

Answers (2)

Michał Fita
Michał Fita

Reputation: 1329

Above the advice from @lukas-kalbertodt in idiomatic Rust you normally create iterator over existing vector, then using filtering techniques you collect data to the new vector. Please avoid very inefficient removal from vectors.

Upvotes: 0

Lukas Kalbertodt
Lukas Kalbertodt

Reputation: 88886

Your immediate problem is that after you called remove three times, your loop continues to run. The loop range (0..repository_urls.len() - 1) is only evaluated at the very beginning of the loop. But now the vector length has changed and accessing the vector via repository_urls[i + 1] then fails. You can fix this by adding a break after your removes.

For command line argument parsing, it's usually advisable to use a crate. Doing it manually usually leads to spaghetti code and subtle bugs. I can very much recommend structopt. It's really easy to add it to your application.

Upvotes: 3

Related Questions