为何lazy_static!变量在符号表中的大小为0?
关于lazy_static生成的HashMap符号大小为0的疑问
测试代码
#[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() { // 第一次访问`HASHMAP`时触发初始化 println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap()); // 后续访问直接返回已初始化完成的值 println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap()); }
符号表查看结果
执行命令: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
可以看到HASHMAP对应的符号大小为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
该符号位于rodata段中,对应段的大小也为0。
疑问与解答
疑问
既然长度为0,是否意味着无法存储数据?HashMap的内存在运行时分配在何处?
解答
符号大小为0不代表无法存储数据,这是lazy_static!宏的实现特性导致的:
lazy_static!生成的HASHMAP本质是一个初始化占位符,编译期它仅标记初始化逻辑的入口,不会把HashMap的实际数据写入可执行文件的静态段,所以符号表和对应rodata段的大小都显示为0。- 当程序第一次访问
HASHMAP时,会触发你定义的初始化闭包,此时才会在堆内存上动态分配空间,构建并填充HashMap实例。 - 后续所有对
HASHMAP的访问,都会直接返回已初始化完成的堆上实例,避免重复执行初始化逻辑。
简单来说,这个符号只是负责触发初始化的"开关",实际的数据全在运行时分配的堆内存里,和静态段无关。
内容的提问来源于stack exchange,提问作者super_jh
相关产品推荐
相关产品推荐

