Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 向量中字符串的内存分配_C++_C++11_Vector - Fatal编程技术网

C++ 向量中字符串的内存分配

C++ 向量中字符串的内存分配,c++,c++11,vector,C++,C++11,Vector,如果向量始终提供连续内存存储,编译器如何将内存分配给空std::字符串 我有一个向量,我已经将std:string作为私有成员推送到了很多类。然后,我将对向量的引用作为参数传递给另一个方法 堆中其他地方的字符串数据是否从向量的连续数组引用?为std::string分配内存是琐碎的 在内部,它将具有某种指针,指向实际字符串数据将存储在其中的内存块。因此,为std::string分配内存只是为指针、大小或其他对象分配空间的问题,可能还有一些原语 例如,如果您有一个std::vector,那么向量很容

如果向量始终提供连续内存存储,编译器如何将内存分配给空std::字符串

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


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

std::string
分配内存是琐碎的

在内部,它将具有某种指针,指向实际字符串数据将存储在其中的内存块。因此,为std::string分配内存只是为指针、大小或其他对象分配空间的问题,可能还有一些原语


例如,如果您有一个
std::vector
,那么向量很容易为
std::string
分配空间,因为对于某个常量
k
,它们只是
k
字节。此分配中将不涉及字符串数据。

std::string
分配内存是一件微不足道的事情

在内部,它将具有某种指针,指向实际字符串数据将存储在其中的内存块。因此,为std::string分配内存只是为指针、大小或其他对象分配空间的问题,可能还有一些原语


例如,如果您有一个
std::vector
,那么向量很容易为
std::string
分配空间,因为对于某个常量
k
,它们只是
k
字节。字符串数据将不参与此分配。

在这种情况下,内存中实际发生的情况的详细信息完全取决于您使用的特定STL实现

话虽如此,我的印象是,在大多数实现中,向量和字符串都是通过以下方式实现的(非常简化):

模板
类向量
{
//...
私人:
T*_数据;
};
类字符串
{
私人:
char_smallStringsBuffer[kSmallSize];
char*_bigStringsBuffer;
};
向量的数据根据容量在堆上动态分配(容量在默认初始化时具有默认值,并在向向量添加元素时增长)

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

您描述的示例类似于:

void MyFunction(const vector<string>& myVector)
{
  // ...
}

int main()
{
  vector<string> v = ...;

  // ...

  MyFunction(v);

  // ...

  return 0;
}
void MyFunction(常量向量和myVector)
{
// ...
}
int main()
{
向量v=。。。;
// ...
MyFunction(v);
// ...
返回0;
}
在这种特殊情况下,只有向量v的基本数据将在堆栈中,因为v._数据将分配在堆上。如果v的容量为N,则v._数据在堆中的大小将为sizeof(string)*N,其中字符串的大小是一个常量,取决于kSmallSize*sizeof(char)+sizeof(char*),具体取决于上述字符串的定义

至于连续数据,只有当向量中收集的所有字符串的字符数少于kSmallSize时,它们的数据在内存中才会“几乎”连续


这是性能关键代码的一个重要考虑因素,但老实说,我不认为大多数人会在这种情况下依赖标准STL的向量和字符串,因为实现细节会随着时间的推移以及在不同的平台和编译器上发生变化。此外,每当您的代码超出“快速”路径时,您都不会注意到,除非出现难以控制的延迟峰值。

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

话虽如此,我的印象是,在大多数实现中,向量和字符串都是通过以下方式实现的(非常简化):

模板
类向量
{
//...
私人:
T*_数据;
};
类字符串
{
私人:
char_smallStringsBuffer[kSmallSize];
char*_bigStringsBuffer;
};
向量的数据根据容量在堆上动态分配(容量在默认初始化时具有默认值,并在向向量添加元素时增长)

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

您描述的示例类似于:

void MyFunction(const vector<string>& myVector)
{
  // ...
}

int main()
{
  vector<string> v = ...;

  // ...

  MyFunction(v);

  // ...

  return 0;
}
void MyFunction(常量向量和myVector)
{
// ...
}
int main()
{
向量v=。。。;
// ...
MyFunction(v);
// ...
返回0;
}
在这种特殊情况下,只有向量v的基本数据将在堆栈中,因为v._数据将分配在堆上。如果v的容量为N,则v._数据在堆中的大小将为sizeof(string)*N,其中字符串的大小是一个常量,取决于kSmallSize*sizeof(char)+sizeof(char*),具体取决于上述字符串的定义

至于连续数据,只有当向量中收集的所有字符串的字符数少于kSmallSize时,它们的数据在内存中才会“几乎”连续

这是性能关键代码的一个重要考虑因素,但老实说,我不认为大多数人会在这种情况下依赖标准STL的向量和字符串,因为实现细节会随着时间的推移以及在不同的平台和编译器上发生变化。此外,每当您的代码超出“快速”路径时,您都不会注意到,除非出现难以控制的延迟峰值