繁体   English   中英

向量中字符串的内存分配

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM