【问题标题】:how memory allocation happens for map and string in c++c++中map和string的内存分配是如何发生的
【发布时间】:2015-07-17 16:03:06
【问题描述】:

我正在使用map<string,string> 类型的全局声明。

  1. 如果我执行代码,字符串是在动态内存中创建的吗?
  2. 地图是在动态内存还是静态内存上创建的?

-

#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++ string dictionary memory-management dynamic


    【解决方案1】:

    有一个固定大小的对象表示地图本身,您已将其设为全局(与静态存储相同)。这将具有某种形式的指向动态内存的指针,其中包含映射的可变大小内容。这包括动态内存中的字符串,还包括动态内存中的其他内容(取决于实现)。

    【讨论】:

    • 谈到字符串时,必须考虑 SSO。使用 VC++,OP 示例中小字符串的内存不会被动态分配。
    • 映射中每个字符串的基本(固定大小)对象是动态分配的,因此 SSO 不会改变字符串是动态分配的事实,只是分配的细节。
    • 当然可以,但是从字符串的POV来看,不是动态的。映射中的指针直接指向字符串数据,而不是另一个指针,或者可以这么说。
    【解决方案2】:

    这个问题的正确、完整答案可能比人们想象的要复杂。我会给你一些提示:

    • C++ 标准将内存管理的细节留给实现。你真的应该不要太在意。专注于应用程序逻辑的语义,将内存管理留给编译器。

    • 与原始数组(或 std::array,就此而言)不同,std::mapstd::string(实际上,std::basic_string)是在执行期间大小可以改变的容器,因此类通常(但不是总是,见下文)不能包含所有元素本身。相反,它们将包含一个指向动态分配内存的指针,其中保存了实际内容。 std::mapstd::string 对象本身的大小(字面意思是sizeof)与它们当前的内容无关。

    • 对于动态分配,std::mapstd::string 默认使用 std::allocatorstd::allocatoruses placement new 分配内存(不是new[])。

    • 理论上,您可以使用自定义分配器而不是默认分配器,以完全不同的方式执行任何内存分配,尽管很少这样做。

      李>
    • std::string 可以使用Small-String Optimisation (SSO) 实现,在这种情况下,对于小字符串将完全没有动态分配。 Visual C++ 使用这种技术。

    • Copy-on-Write (COW) 是另一种实现字符串的传统方法,它基于相同的字符串可以共享相同的动态分配的内容这一理念。在这种情况下,多个std::string 对象中的指针将指向同一个地址。但是,这种技术在多线程场景中一直有问题,并且实际上已被 C++11 禁止;为了完整起见,我刚刚提到它。

    • 从 C++11 开始,std::string 的内容被正式要求是连续的,即一个接一个地存储在内存中,这样你就可以获取第一个元素并将内容视为数组。

    【讨论】:

      【解决方案3】:

      实际上这个映射需要被移动到共享内存所以想知道内存是如何分配的,如果我想用字符串移动映射我需要遵循不同形式的内存管理。

      如果有人知道如何实现这一点,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-21
        • 2021-11-06
        • 1970-01-01
        • 2021-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多