【问题标题】:Strange sizeof(std::map)奇怪的 sizeof(std::map)
【发布时间】:2017-10-22 13:04:06
【问题描述】:

我正在使用 std::map,但无法理解它消耗了多少内存。

我有以下地图定义:

CKey {
 long x;
 int y;
 int z;
 bool operator<(const CKey& l) const;
};

CValue {
 int data1;
 int data2;
}

std::map<CKey, CValue> map;
std::cout << "sizeof() = " << sizeof(map) << " Max #Elms = " << map.max_size();

(无论是在向地图中插入元素之前还是之后) 我明白了。

sizeof() = 48
Max_Size = 329406144173384850
  1. 如果sizeof(map) = 48,怎么可能包含329406144173384850元素?
  2. 映射是否将&lt;CKey,Cvalue&gt; 保存在其他内存(堆?)中

【问题讨论】:

  • en.cppreference.com/w/cpp/container/map/max_size max_size 会给你在给定当前系统的情况下你可以在地图中放置的最大元素数量,而不是地图中的对数。
  • sizeof 运算符返回 object 的大小,而不是它包含的数据。它只是所有成员的sizeof 的总和(加上潜在的填充)。这就像在做sizeof(some_pointer),它返回指针的大小,而不是指向的数据的大小。
  • MaxSize 不是你想的那样,Sizeof 也不是你想的那样。 RTFM 是为了一切,而不是仅仅通过他们的名字来猜测。
  • c++ sizeof() of a class with functions 的可能重复项——它不是“完全重复的”,因为它询问的是“具有函数的类”,但很难否认 std::map 是一个类,而且它有方法。
  • 你需要map.size(),而不是sizeof(map)。

标签: c++ stdmap


【解决方案1】:

在 C 和 C++ 中,sizeof 运算符告诉您类的实例将占用多少字节的 stack 空间。

与其他标准容器(std::array 除外)一样,map 在使用默认分配器时会在 堆 上分配其元素。这意味着它的静态大小(即sizeof 返回的内容)不依赖于map 中的元素数量。

您可以使用size() 成员函数找出map 中有多少元素。另一方面,max_size() 成员函数告诉您map 理论上可以存储多少元素——在 64 位系统上,您几乎肯定会受到系统上 RAM 数量的限制,而不是什么max_size() 返回。

实际上计算出map 的总内存使用量(堆栈和堆)并不是一件容易的事:在 C++17 中,您可能可以执行类似的操作

sizeof(map) + map.size() * sizeof(typename map::node_type);

给你一个粗略的猜测,但实际上这将取决于你的标准库的实现细节。

【讨论】:

    【解决方案2】:

    std::map 定义了以下方法

    max_size()

    返回容器由于系统或库实现限制而能够容纳的最大元素数

    size()

    返回容器中的元素个数

    因此,以下计算将为您提供一个很好的 近似 地图的实际大小(以 字节 为单位)(假设 Key 和 Value 类型是原始类型的结构):

    sizeof(mymap) + mymap.size() * (sizeof(decltype(mymap)::key_type) + sizeof(decltype(mymap)::mapped_type))
    

    【讨论】:

    • the following calculation will give you the actual size of the map in bytes - 我真的怀疑它会不会。 IIRC Map 通常实现为 tree,因此您将有 至少 log(N) 指针开销
    • @quetzalcoatl,你是 100% 正确的。我修正了我的错误,明确指出这是一个近似值!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多