向量

时间:2017-03-21 05:47:44

标签: c++ c++11 vector

如果向量总是提供连续的内存存储,那么编译器如何分配内存以清空std :: strings?

我有一个向量,我用std:string作为私有成员推送了许多类。然后我将对向量的引用作为另一个方法的参数传递。

堆中其他位置的字符串数据是否是从向量的连续数组引用的?

2 个答案:

答案 0 :(得分:4)

std::string分配内存琐碎

在内部,它会有某种指针指向一个内存块,其中将存储实际的字符串数据。因此,为std :: string分配内存只是为指针,size_t或其他东西分配空间,可能还有几个原语。

例如,如果您有std::vector<std::string>,则向量可以轻松为std::string分配空间,因为它们只是k每个字节都有一些常量k。字符串数据不会参与此分配。

答案 1 :(得分:1)

在这种情况下,内存中真正发生的事情的细节完全取决于您正在使用的特定STL实现。

话虽如此,我的印象是,在大多数实现中,vector和string都是用( very 简化)之类的方式实现的:

template<typename T>
class vector
{
  //...
  private:
    T* _data;
};

class string
{
  private:
    char _smallStringsBuffer[kSmallSize];
    char* _bigStringsBuffer;
};

矢量的数据是根据容量在默认情况下在堆上动态分配的(默认初始化时具有默认值,在向量中添加元素时会增长)。

字符串的数据静态分配给小字符串(依赖于实现的值&#34; small&#34;),然后在字符串变大时动态分配。出于多种原因,情况就是如此,但主要是为了更有效地处理小字符串。

您描述的示例如下:

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更少的字符时,它们的数据才会是&#34;几乎&#34;在记忆中连续。

这是性能关键代码的一个重要考虑因素,但说实话,我不认为大多数人会依赖标准STL的向量和字符串来处理这种情况,因为实现细节可能会改变随着时间的推移,在不同的平台和编译器上。此外,每当你的代码超出&#34; fast&#34;路径,你不会注意到,除了延迟的尖峰将难以控制。