How rust store Strings in arrays?

563 Views Asked by At

As i know from c/c++ and general knowledge of data structures, arrays are structured as sequential memory blocks with constant size. So if I create an array of five i32 variables then array size bill be 5x4 bytes, But when I create array of strings how does it's handled. Does it creates array of pointers and stores only memory address of string objects?

I asked question on rust but anyone knows a method how any language handles this situation can answer, probably it will be same method for every language.

3

There are 3 best solutions below

0
Finomnis On BEST ANSWER

The problem is that, as you point out, elements in an array must have a size known at compile time (called the Sized auto-trait in Rust). String is indeed Sized because it does not store its content in the String stack object, but instead in memory allocated on the heap. So yes, simplified you could say that a String array is an array of pointers.

You can see this here:

fn main() {
    let s1 = String::from("A.");
    let s2 = String::from("This is a very long string!");

    println!("String object size:");
    println!("s1: {} bytes", std::mem::size_of_val(&s1));
    println!("s2: {} bytes", std::mem::size_of_val(&s2));
    println!("");

    println!("Actual size of the contained data:");
    println!("s1: {} bytes", s1.as_str().len());
    println!("s2: {} bytes", s2.as_str().len());
    println!("");

    println!("In an array:");
    let arr = [s1, s2];
    println!("arr: {} bytes", std::mem::size_of_val(&arr));
}
String object size:
s1: 24 bytes
s2: 24 bytes

Actual size of the contained data:
s1: 2 bytes
s2: 27 bytes

In an array:
arr: 48 bytes
0
Jeremy Meadows On

A String is literally a byte vector (source code). A Vec is essentially a fat-pointer with a length and capacity. You are right that the array would store pointers, each pointer just has some additional metadata associated with it so that it knows how big the objects are, as well as when/how to allocate more memory since vectors can grow/shrink.

0
jthulhu On

Note that Rust as a marker trait for this kind of issues, which is Sized. A type T is Sized (denoted T: Sized) if its size at compile time in known. As you well noted, some types are not sized, including str (denoted str: !Sized). str is, roughly speaking, a utf-8 valid byte sequence. String, on the other hand, is, roughly speaking, a pointer to a heap-allocated str, therefore String: sized. This is why Rust will accept something like [String; 5], but not [str; 5].

Note that, because str: !Sized, and because most of the time you still want to manipulate Sized types, you'll often see &str. It's very rare that a function signature takes a str and not a &str.