“复合”数据结构在哪里,如包含String的数组存储?阵列的大小是固定的,但阵列的组件大小可能会发生变化 . let array:[String; 3] = [“A”,“B”,“C”];
它存储在堆栈和堆中:
// [String; 3]
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| data | len | cap | data | len | cap | data | len | cap |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| | |
\ \ \
+-+ +-+ +-+
|A| |B| |C|
+-+ +-+ +-+
2 回答
String
刚刚包裹Vec<u8>
. 所以这适用于所有Vecs
.Vec
在堆栈上有一个固定的大小:它的长度,容量和指向存储实际内容的堆的指针 .因此,在堆栈上有一个三个
Strings
的数组意味着这些字符串的"metadata"在堆栈上(长度,容量和指向数据的指针) .这些字符串的实际数据虽然存储在堆上,因为正确识别时它的长度可变 .
Both .
术语点:在讨论类型的内存布局时,不应该谈论堆栈与堆,而是关于内联与离线1:
内联意味着数据就在这里,
offline表示数据在指针后面(无论指向何处)都可用 .
一个简单的例子,整数是内联存储的:
典型的
struct Point { x: i32, y: i32 }
也以内联方式存储:String
(通常表示为struct String { data: *mut u8, len: usize, cap: usize }
)内联和离线存储:内联部分是3个指针的存储空间,而离线部分是一个堆分配的记录,其中包含字符串
"Hello, World!"
的内容 .但是,内联并不总是意味着堆栈 . A
Box<Point>
:将其
Point
(将其数据成员内联存储)存储在堆上!同样,离线并不总是意味着堆:
这里,
r
是一个引用(指针),它指向i
,而i
在堆栈中!1是的,我正在做这个,更好的条款将不胜感激 .
那么,回到问题:
这是一个近似值,如上所述,
String
有一些内联数据(指针,长度和容量),有些数据在堆上(字符串内容) .它存储在堆栈和堆中:
这是9个指针的内联数据(在堆栈中),以及堆上的3个单独分配 .
数据成员总是内联的,指针和引用可能指向脱机数据,这些数据可能在堆上,堆栈上等...