Allocation of memory inside for new variable inside a loop


#1

I am learning Rust. I am following the book second edition, and I was doing the exercises given at the end of this chapter.

I did Convert temperatures between Fahrenheit and Celsius. The code is:

use std::io;

fn main() {
    println!("Welcome to temperature conversion tool.");
    println!("---------------------------------------");

    loop {
        let mut choice = String::new();

        println!("1. Fahrenheit to Celsius");
        println!("2. Celsius to Fahrenheit");
        println!("0. Quit");
        println!("Enter your choice");

        io::stdin().read_line(&mut choice)
            .expect("Failed to read input");

        let choice: u32 = match choice.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        if choice == 1 {
            let mut temperature = String::new();

            println!("Enter Fahrenheit temperature");

            io::stdin().read_line(&mut temperature)
                .expect("Failed to read input");

            let temperature: f32 = match temperature.trim().parse() {
                Ok(num) => num,
                Err(_) => continue,
            };

            println!("Celsius temperature is {}", fahrenheit_to_celsius(temperature));
        } else if choice == 2 {
            let mut temperature = String::new();

            println!("Enter Celsius temperature");

            io::stdin().read_line(&mut temperature)
                .expect("Failed to read input");

            let temperature: f32 = match temperature.trim().parse() {
                Ok(num) => num,
                Err(_) => continue,
            };

            println!("Fahrenheit temperature is {}", celsius_to_fahrenheit(temperature));
        } else if choice == 0 {
            break;
        } else {
            println!("Invalid choice");
            continue;
        }
    }
}

fn fahrenheit_to_celsius(x: f32) -> f32 {
    (x - 32.0) * (5.0 / 9.0)
}

fn celsius_to_fahrenheit(x: f32) -> f32 {
    x * 9.0 / 5.0 + 32.0
}

You can see that inside the loop and if condition I am creating mutable variables.

I would like to know how it impacts the system I am running this program on. For example,

  • Does it allocates a new placeholder in the system memory for the new variable? Everytime a new variable is declared?

Thank you.


Does the `rustc` optimizer avoid unnecessary memory allocations in loops?
#2

The String::new() call itself won’t allocate memory on the heap - String::new() (presumably) just initializes its internal pointer to null. However, every time you call read_line with a mutable borrow for those brand new mutable string variables, you will get a memory allocation. If you hoist the String variable declarations outside of the the loop structure, you may get fewer allocations - the String should only need to be re-allocated when reading in a larger string.

It’s important to note that Rust uses RAII, which is just a fancy way of saying all resources (including memory) are freed when they go out of scope. So when the “choice” string goes out of scope at the end of a loop iteration, any allocated memory it holds will be returned to the heap. So, if your concern is memory leaks, don’t be concerned. As a rule of thumb, if no references to your resource are left, then the resource itself has been freed.


#3

It initializes it to 0x1, but this is an implementation detail. You’re correct that it won’t allocate, and this is guaranteed by its docs.


#4

It actually initializes it to std::mem::align_of::<T>() :slight_smile: