是一个String数组,例如[String; 3]存储在堆栈或堆上?

Gre*_*reg 3 rust

Rust书指定:

使堆栈快速运行的另一个特性是堆栈上的所有数据必须占用已知的固定大小.

它还表示String存储在堆上,因为大小未知并且可能会发生变异.

"复合"数据结构在哪里,如包含String存储的数组?阵列的大小是固定的,但阵列的组件大小可能会发生变化.

let array: [String; 3] = ["A","B","C"];
Run Code Online (Sandbox Code Playgroud)

存储此类"复合"数据类型的规则是什么?

Mat*_* M. 12

两者.


术语点:在讨论类型的内存布局时,不应该谈论堆栈与堆,而是关于内联与离线1:

  • 内联意味着数据就在这里,
  • 离线意味着数据在指针后面可用(无论它指向何处).

一个简单的例子,整数是内联存储的:

//  i32
+---+
| 3 |
+---+
Run Code Online (Sandbox Code Playgroud)

典型的struct Point { x: i32, y: i32 }内联也存储:

//  Point
+---+---+
| x | y |
+---+---+
Run Code Online (Sandbox Code Playgroud)

String,通常被表示为struct String { data: *mut u8, len: usize, cap: usize }存储在线和离线:

//   String
+-------+-------+-------+
| data  |  len  |  cap  |
+-------+-------+-------+
    |
     \
      +-------------+
      |Hello, World!|
      +-------------+
Run Code Online (Sandbox Code Playgroud)

内联部分是3个指针的存储空间,而离线部分是一个堆分配的记录,其中包含字符串的内容"Hello, World!".

但是,内联并不总是意味着堆栈.答Box<Point>:

//  Box<Point>
+-------+
| data  |
+-------+
    |
     \
      +---+---+
      | x | y |
      +---+---+
Run Code Online (Sandbox Code Playgroud)

将其Point(将其数据成员内联存储)存储在堆上!

同样,离线并不总是意味着:

fn main() {
    let i = 3;
    let r = &i;
}
Run Code Online (Sandbox Code Playgroud)

这里r是一个引用(指针),它指向ii位于堆栈中!

1 是的,我正在做这个,更好的条款将不胜感激.


那么,回到问题:

它还表示String存储在堆上,因为大小未知并且可能会发生变异.

这是一个近似值,如上所述,String它的一些数据内联(指针,长度和容量)和一些在堆上(字符串内容).

"复合"数据结构在哪里,如包含String存储的数组?阵列的大小是固定的,但阵列的组件大小可能会发生变化.

let array: [String; 3] = ["A","B","C"];
Run Code Online (Sandbox Code Playgroud)

它存储在堆栈和堆中:

//  [String; 3]
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| data  |  len  |  cap  | data  |  len  |  cap  | data  |  len  |  cap  |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
    |                       |                       |    
     \                       \                       \
      +-+                     +-+                     +-+
      |A|                     |B|                     |C|
      +-+                     +-+                     +-+
Run Code Online (Sandbox Code Playgroud)

这是9个指针的内联数据(在堆栈中),以及堆上的3个单独分配.

存储此类"复合"数据类型的规则是什么?

数据成员总是内联的,指针和引用可能指向脱机数据,这些数据可能在堆上,堆栈上等...


JDe*_*ler 6

String只是包裹Vec<u8>。所以这适用于所有Vecs

AVec在堆栈上具有固定大小:它的长度、容量和指向存储实际内容的堆的指针。

因此,堆栈上有一个包含三个的数组Strings意味着这些字符串的“元数据”位于堆栈上(长度、容量和指向数据的指针)。

这些字符串的实际数据存储在堆上,因为它的长度是可变的,正如您正确识别的那样。