The following rust code, in x86_64 platform compilation.
#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref HASHMAP: HashMap<u32, &'static str> = {
let mut m = HashMap::new();
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
m
};
}
fn main() {
// First access to `HASHMAP` initializes it
println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
// Any further access to `HASHMAP` just returns the computed value
println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap());
}
I use the readelf command to view the size of the HASHMAP variable in the symbol table:
readelf -sW target/debug/deps/section_test-4d7d6a03c56fdde3.o
Symbol table '.symtab' contains 590 entries:
Num: Value Size Type Bind Vis Ndx Name
452: 0000000000000000 0 OBJECT LOCAL DEFAULT 498 _ZN12section_test7HASHMAP17hbc6de818c577d166E
We can see The Size is 0.
readelf -SW target/debug/deps/section_test-4d7d6a03c56fdde3.o
There are 527 section headers, starting at offset 0x98690:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[498] .rodata._ZN12section_test7HASHMAP17hbc6de818c577d166E PROGBITS 0000000000000000 00b528 000000 00 A 0 0 1
Let's take a look at the section where the symbol is located,The symbol is located in the rodata section and the Size of the section is also 0.
Since the length is 0, does it mean that no data can be stored, and where is the HashMap memory assigned at runtime? Can I define a variable with a length of 0 in the symbol table in C language?
lazy_static
creates an empty type and value that are equivalent to:(Source code)
Then it implements
Deref
for this type so that it can initialize the real value dynamically the first time you try to access it (the real value is hidden in a static value inside a private function called byderef
).BTW note that the keys and values will be allocated and stored on the heap when the
HashMap
is initialized, only theHashMap
struct itself is in the hidden static value.