c++中map和string的内存分配方式
how memory allocation happens for map and string in c++
我使用map<string,string>
类型的全局声明。
- 如果我执行代码,字符串是在动态内存中创建的吗?
- 映射是在动态内存还是静态内存上创建的?
#include <iostream>
#include <map>
#include <string>
std::map<std::string, std::string> mymap;
class myObject
{
public:
myObject()
{
mymap["A"] = "AString";
mymap["B"] = "BString";
mymap["C"] = "CString";
}
};
int main()
{
myObject obj1;
std::cout << mymap["B"] << std::endl;
return 1;
}
有一个固定大小的对象表示映射本身,您将其设置为全局(与静态存储类型相同)。它将具有某种形式的指针,指向包含映射的可变大小内容的动态内存。这包括动态内存中的字符串,但也包括动态内存中的其他内容(取决于实现)。
这个问题的正确、完整的答案可能比人们想象的要复杂得多。我给你一些提示:
-
c++标准将内存管理的细节留给实现。你真的不应该太在意这个。把精力集中在应用程序逻辑的语义上,把内存管理留给编译器。
-
与原始数组(或
std::array
)不同,std::map
和std::string
(实际上是std::basic_string
)是容器,其大小可以在执行过程中更改,因此类通常(但不总是,见下文)不能包含所有元素本身。它们将包含一个指向动态分配内存的指针,其中保存了实际的内容。std::map
和std::string
对象本身的大小(字面上是sizeof
)与它们当前的内容无关。 -
动态分配时,
std::map
和std::string
默认使用std::allocator
。std::allocator
使用placement new来分配内存(new[]
不使用)。 -
理论上,您可以使用自定义分配器而不是默认分配器,以完全不同的方式执行任何内存分配,尽管很少这样做。
-
std::string
可以使用小字符串优化(SSO)实现,在这种情况下,对于小字符串将根本没有动态分配。Visual c++使用了这种技术。 -
Copy-on-Write (COW)是另一种传统的实现字符串的方法,基于相同的字符串可以共享相同的动态分配的内容的想法。在这种情况下,多个
std::string
对象中的指针将指向相同的地址。然而,这种技术在多线程场景中一直存在问题,并且在c++ 11中实际上是不允许的;我只是为了完整起见才提到它。 -
从c++ 11开始,
std::string
的内容被正式要求是连续的,即一个接一个地存储在内存中,这样你就可以取第一个元素的地址,并将内容视为一个数组。
实际上这个map<string,string>需要移动到共享内存,所以想知道内存是如何分配的,如果我想移动带有字符串的map,我需要遵循不同形式的内存管理。
如果有人知道如何做到这一点,请告诉我。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配