向量中字符串的内存分配
Memory allocation for strings in vectors
如果向量始终提供连续的内存存储,编译器如何为空 std::string 分配内存?
我有一个向量,我已经将许多类推送到 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 的向量和字符串,因为实现细节会随着时间的推移以及不同的平台和编译器而变化。此外,每当你的代码超出"快速"路径时,你不会注意到,除非延迟峰值很难控制。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配