[英]Memory allocation for strings in vectors
如果向量始终提供连续的内存存储,则编译器如何将内存分配给空的std :: strings?
我有一个向量,已将std:string作为私有成员推入了多个类。 然后,我将对向量的引用作为另一个方法的参数传递。
是否从向量的连续数组引用了堆中其他位置的字符串数据?
为std::string
分配内存是微不足道的 。
在内部,它将具有某种指针,该指针指向将存储实际字符串数据的内存块。 因此,为std :: string分配内存仅是为指针, size_t
东西以及可能还有更多其他基元分配空间的问题。
例如,如果您有一个std::vector<std::string>
,则向量很容易为std::string
分配空间,因为它们对于某个常数k
每个k
个字节。 字符串数据将不参与此分配。
在这种情况下,实际发生在内存中的详细信息完全取决于您使用的特定STL实现。
话虽这么说,我的印象是,在大多数实现中,矢量和字符串都是通过( 非常简化)的方式实现的:
template<typename T>
class vector
{
//...
private:
T* _data;
};
class string
{
private:
char _smallStringsBuffer[kSmallSize];
char* _bigStringsBuffer;
};
向量的数据根据容量(在默认初始化时具有默认值,并在向向量中添加元素时增加)自动在堆上分配。
字符串的数据静态分配给小字符串(取决于实现的值“ small”),然后在字符串变大时动态分配。 出于多种原因会出现这种情况,但主要是为了更有效地处理小字符串。
您描述的示例类似于:
void MyFunction(const vector<string>& myVector)
{
// ...
}
int main()
{
vector<string> v = ...;
// ...
MyFunction(v);
// ...
return 0;
}
在这种特殊情况下,向量v的基本数据将位于堆栈中,因为v._data将分配在堆中。 如果v的容量为N ,则v._data在堆中的大小将为sizeof(string)* N,其中字符串的大小是一个常数,取决于kSmallSize * sizeof(char)+ sizeof(char *),基于上面字符串的定义。
对于连续数据,仅当向量中收集的所有字符串的字符数少于kSmallSize时,它们的数据才会在内存中“几乎”连续。
对于性能至关重要的代码,这是一个重要的考虑因素,但是老实说,我不认为大多数人会在这种情况下依赖标准STL的向量和字符串,因为实现细节可能会随时间以及在不同的平台和编译器上发生变化。 此外,每当您的代码超出“快速”路径时,您将不会注意到,除非出现了难以控制的延迟峰值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.