C++:字符串向量的随机访问时间如何工作?

Posted

技术标签:

【中文标题】C++:字符串向量的随机访问时间如何工作?【英文标题】:C++: How does string vectors' random access time work? 【发布时间】:2010-09-20 16:33:24 【问题描述】:

我知道一个简单的 int 向量有 O(1) 的随机访问时间,因为它很容易计算第 x 个元素的位置,假设所有元素都具有相同的大小。

现在字符串向量怎么样了?

由于字符串长度不同,它不可能有 O(1) 的随机访问时间,对吗?如果可以,其背后的逻辑是什么?

谢谢。

更新:

答案非常简洁明了,谢谢大家的帮助。 我接受了乔伊的回答,因为它简单易懂。

【问题讨论】:

一个字符串和它的内容不是一回事。对象的大小始终不变。 【参考方案1】:

向量确实有 O(1) 的访问时间。

字符串对象的大小都是相同的(在给定的实现上),不管它们代表的字符串的大小。通常,字符串对象包含一个指向已分配内存的指针,该内存保存字符串数据。

所以,如果sstd::string,那么sizeof s 是常量并且等于sizeof(std::string),但s.size() 取决于字符串值。向量只关心sizeof(std::string)

【讨论】:

@FredOverflow:谢谢。我重新阅读了自己的答案,并意识到我可以更清楚地了解“字符串对象的大小”和“它所代表的字符串的大小”的含义:-) 【参考方案2】:

字符串引用存储在一个位置。字符串可以存储在内存中的任何位置。所以,你仍然会得到 O(1) 的随机访问时间。

 ---------------------------
| 4000 | 4200 | 5000 | 6300 |  <- data
 ---------------------------
 [1000] [1004] [1008]  [1012]  <- address


 [4000]    [4200]    [5000]     [6300]     <- starting address
"string1" "string2" "string3"  "string4"   <- string

【讨论】:

非常漂亮的视觉表现!【参考方案3】:

因为字符串对象与任何其他类型一样具有固定大小。不同的是,字符串对象在堆上存储了自己的字符串,并且它保存了一个指向大小固定的字符串的指针。

【讨论】:

通过小字符串优化,它也可以直接存储在字符串实例中。【参考方案4】:

std::string 中的实际字符串通常只是一个指针。一个字符串的大小总是相同的,即使它所包含的字符串的长度不同。

【讨论】:

Erm.. 通常它比指针大一些(通常有一个计数器用于字符串的大小和至少分配的内存块的大小)。但仍然不是字符串本身的大小。 是的,我指的是数据的实际内容,可能还有更多【参考方案5】:

您已经得到了很多答案(例如,Steve Jessop 和 AraK 的答案),这些答案大多是正确的。我将仅添加一个小细节:std::string 的许多当前实现使用所谓的短字符串优化 (SSO),这意味着它们在字符串对象本身中分配一小块固定的空间,可用于存储短字符串,只有当/如果长度超过字符串对象本身分配的长度时,它才会在堆上分配单独的空间来存储数据。

就字符串向量而言,这并没有真正的区别:每个字符串对象都有一个固定的大小,而不管字符串本身的长度如何。不同之处在于 SSO 的固定大小更大——在许多情况下,字符串对象没有在堆上分配块来保存实际数据。

【讨论】:

你确定 libstdc++ 属于“许多当前的实现”吗? @sellibitze:我不记得了。我见过至少一个 g++ 库有它,另一个没有,但是我不记得哪个是哪个... GNU 的 std::string 大小为 4(在我的机器上)。它只是一个指向已分配 blob 的指针,其中包含所有元数据和字符串数据。与短字符串优化相反。

以上是关于C++:字符串向量的随机访问时间如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

使用 unordered_map 向量的 C++ 图形,在访问时添加随机数据,如 graph[i][j]

如何从 C++ 中的“指向对象的指针”向量访问对象

(C++) 创建可以从函数访问的动态全局数组/向量

如何在 C++ 中访问类对象向量中的对象?

如何在 C++ 中访问向量中的子实例

如何访问在 C++ 中通过引用传递的列表/向量的元素