Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

creates temporary which is freed while still in use when reading path of DirEntry

I’m trying to read all files in a folder, as simple as that. And then filter for mp4 extensions. But I get following error:

create a temporary which is freed error

I don’t understand, how in the following code, the e.path statement could "create a temporary". (The whole code is obviously in them same "Ok" closure.). Is there some special stuff happening in the path() method? I could not find anything strange in the documentation.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

let paths = fs::read_dir(&folder).unwrap();

for path in paths {
    match path {
        Ok(e) => {
            let fullPath = e.path();
            let extension = e
                .path()
                .extension()
                .expect("Error getting extension")
                .to_str()
                .expect("Could not convert extensions to string");
            println!("{}", extension)
        }

        _ => {}
    }

I tried numerous things and stuff like .path().metadata() does not throw this error. Only when in combination with extension() this seems to be happening? It’s really confusing me, how a task this simple becomes so complex.

>Solution :

DirEntry::path() returns a PathBuf, and PathBuf::extension() returns an Option<&OsStr>. As you can see, the OsStr is borrowed from the original PathBuf / Path. The problem is, you’re trying to bind the extension to a variable, but you do not assign the PathBuf that is borrowed from to a variable as well.

So the compiler is correct in saying that the PathBuf is temporary, and will be dropped after your let extension = ... statement, and thus extension can not keep pointing to it.

You’re already doing the right thing – assigning another copy of that PathBuf to fullPath. So you can just borrow the extension from it.

Here’s a fully self-contained solution:

use std::fs;

fn main() {
    let folder = "./src";
    let paths = fs::read_dir(&folder).unwrap();

    for path in paths {
        if let Ok(e) = path {
            let full_path = e.path(); // This will live at least as long as `extension`, so
                                      // borrowing from it is fine.
            let extension = full_path
                .extension()
                .expect("Error getting extension")
                .to_str()
                .expect("Could not convert extensions to string");
            println!("{}", extension)
        }
    }
}

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading