Search code examples
ruststackheap-memory

Are Rust string literal values stored on the Heap?


Consider this simple code

fn main () {
    let mut s: &str = "hello";
    s = "hey";
    println! ("{}", s);
}

I have learnt that the string literals are immutable in nature. I agree with this because the variable 's' here refers to the address of the first character of the value "hello". So basically it's a pointer. Now, if I change the value of s to "hey", that is not replacing the value "hello" 'in-place' somewhere in the memory, but it's is essentially creating a new address location, storing the value "hey" in it and takes that address and point binds it to s. This is well understood.

But what I am confused is, since the size of the variables is a must to be known at compile time for them to be placed on the stack, then are string literals stored on stack too or is it the heap? May be they are stored on the stack for hardcoded values. But what if it is something like this which can be only determined at runtime?

fn main () {
 
    let mut user_input = String::new();
    let stdin = io::stdin(); // We get user input whose size we can't predict 
    stdin.read_line(&mut user_input);
    
    let ab = user_input.as_str(); // taking the value on heap and turning it to string literal and creating a new reference pointer 'ab' on the stack 

    println!("input {}, {} ", user_input, ab);

}

In the above where is the string literal value 'ab' stored? Stack or the Heap?


Solution

  • then are string literals stored on stack too or is it the heap?

    Neither. string literals are generally stored in the "rodata" (read-only data) segment of the generated executable.

    But what if it is something like this which can be only determined at runtime?

    By definition a string literal is not determined at runtime.

    In the above where is the string literal value 'ab' stored? Stack or the Heap?

    A string slice (&str) is not a string literal, it's a pointer to a non-owned string. When you write user_input.as_str(), you just get a second pointer to the string stored in user_input.

    See https://doc.rust-lang.org/book/ch04-03-slices.html