是的,一点没错。
分配的每个内存块都将具有“标题”的恒定开销,以及一个小的可变部分(通常在末尾)。究竟有多少取决于使用的确切 C 运行时库。过去,我通过实验发现每次分配大约 32-64 字节。可变部分是为了应对对齐 - 每个内存块都将对齐到一些不错的甚至 2^n 基地址 - 通常是 8 或 16 个字节。
我不熟悉内部设计std::map
或类似的工作原理,但我非常怀疑他们在那里有特殊的优化。
您可以通过以下方式轻松测试开销:
char *a, *b;
a = new char;
b = new char;
ptrdiff_t diff = a - b;
cout << "a=" << a << " b=" << b << " diff=" << diff;
[请注意,可能是这里的大多数正则,上面的 ab 表达式调用未定义的行为,因为减去一个已分配的地址和另一个的地址,是未定义的行为。这是为了应对没有线性内存地址的机器,例如分段内存或“不同类型的数据存储在基于它们的类型的位置”。以上内容绝对适用于任何不使用分段内存模型且堆中有多个数据段的基于 x86 的操作系统 - 这意味着它肯定适用于 32 位和 64 位模式的 Windows 和 Linux]。
您可能希望以不同的类型运行它 - 请记住,差异在“类型的数量”中,因此如果您将其int *a, *b
设置为“四个字节单位”。您可以制作一个reinterpret_cast<char*>(a) - reinterpret_cast<char *>(b);
[diff 可能是负数,如果你在循环中运行它(不删除a
and b
),你可能会发现一大块内存耗尽的突然跳转,并且运行时库分配了另一个大块]