为之则易,不为|

demo_you

临河而羡鱼,不如归家结网。

[Rust](笔记) 程序内存布局

内存布局

+------------------+  高地址
|      Stack       |  (栈:局部变量、函数调用信息等)
|        ↓         |   - 函数内的局部变量(例如基本类型、结构体等)
|                  |   - 动态分配的类型的元数据(例如 `String` 的指针、长度、容量)
+------------------+
|        ↑         |
|       Heap       |  (堆:动态分配的内存,通常通过 Box、Vec、String 等分配)
|                  |   - `Box::new`、`Vec::new`、`String::from` 创建的内容
|                  |   - 对象的数据存储位置
+------------------+
|       BSS        |  (未初始化的静态/全局变量)
|                  |   - `static mut COUNT: u32;` 等未初始化的变量
+------------------+
|      Data        |  (已初始化的静态/全局变量)
|                  |   - `static NUMBERS: [i32; 3] = [1, 2, 3];` 等初始化的变量
+------------------+
|     .rodata      |  (只读数据段:常量、字符串字面量等)
|                  |   - 字符串字面量 `let s = "hello";`
|                  |   - `const SIZE: u16 = 1024;`
+------------------+
|      Text        |  (代码段:存放编译后的机器码)
|                  |   - 函数的机器码
|                  |   - 程序执行的指令
+------------------+  低地址
  • 只读数据段 .rodata 和 已初始化数据段 Data 中的静态/全局变量有时候会交叉,因为它们都是程序中“静态”部分的一部分。不同的编译器和操作系统对这两个区域的划分可能有所不同。
  • 栈和堆是动态变化的,而其他如数据段、只读数据段等通常是静态的,在程序运行时不会改变。

内存地址与指针

类型 定义 特点 使用场景 Rust示例
内存地址 内存中具体位置的数值标识 只读、基础(仅为地址,不可操作) 低级编程(通过指针间接使用) 0x7ffd5d8e3a40 Rust中不直接使用,通常通过指针间接访问。
指针 存储内存地址的变量 有类型、可以操作所指向的内存,Rust有安全检查 内存引用、间接访问内存 let ptr: *const i32 = &x(裸指针示例,需在unsafe块内使用)
裸指针 不安全的原始指针(即直接操作内存的指针) 无安全检查,允许可变或不可变操作 底层系统编程、FFI等 let raw_ptr = &value as *const i32unsafe块中使用)
胖指针 包含地址和额外元数据(如长度) 存储额外信息(如切片的长度或类型信息),更复杂 切片、动态大小类型 &[i32]&str*const [i32](切片、动态大小类型的示例)

备注:

  1. 内存地址:Rust中一般不会直接使用内存地址,而是通过指针来间接引用。实际使用时,指针的地址值是通过指针类型表示的。
  2. 指针:指针分为可变指针(&mut T)和不可变指针(&T)。unsafe代码中也有裸指针(*const T*mut T)可用于底层操作。
  3. 裸指针:裸指针不受Rust的所有权和借用检查系统的保护,因此在使用时需要特别小心,通常需要在unsafe块中使用。
  4. 胖指针:常用于处理动态大小类型(DST),如切片(&[T])、字符串切片(&str)和trait对象(dyn Trait)等。

栈与堆的小记

栈内存从高位地址向下增长,且栈内存是连续分配的,一般来说操作系统对栈内存的大小都有限制,因此 C 语言中无法创建任意长度的数组。在 Rust 中,main 线程的栈大小是 8MB,普通线程是 2MB,在函数调用时会在其中创建一个临时栈空间,调用结束后 Rust 会让这个栈空间里的对象自动进入 Drop 流程,最后栈顶指针自动移动到上一个调用栈顶,无需程序员手动干预,因而栈内存申请和释放是非常高效的。

与栈相反,堆上内存则是从低位地址向上增长,堆内存通常只受物理内存限制,而且通常是不连续的,因此从性能的角度看,栈往往比堆更高。

本文作者:Code_You

本文链接:https://www.cnblogs.com/coderDemo/p/18677291

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   demo_you  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示