gpt4 book ai didi

c++ - 是否存在与堆内存分配相关的内存开销(例如堆中的标记)?

转载 作者:可可西里 更新时间:2023-11-01 12:45:08 26 4
gpt4 key购买 nike

特别是在使用最近的 Visual Studio C++ 编译器的 Windows 上考虑 C++,我想知道实现:

假设我使用的是发布编译器,并且我不关心内存碎片/打包问题,是否存在与在上分配内存相关的内存开销?如果是这样,那么每次分配大概有多少字节?64 位 代码会比 32 位 更大吗?

我对现代实现了解不多,但我想知道每次分配时是否有标记写入,或者是否有某种维护表(如文件分配表)。

在一个相关的问题上(因为我主要考虑像“ map ”这样的标准库功能),Microsoft 标准库实现是否曾经使用它自己的分配器(对于树节点之类的东西)来优化使用情况?

最佳答案

是的,绝对是。

分配的每个内存块都会有一个恒定的“头”开销,以及一个小的可变部分(通常在末尾)。具体多少取决于所使用的确切 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;

[学究们注意,这可能是这里的大多数常客,上面的 a-b 表达式调用了未定义的行为,因为减去一 block 分配的地址和另一 block 的地址是未定义的行为。这是为了应对没有线性内存地址的机器,例如分段内存或“不同类型的数据存储在基于其类型的位置”。以上应该绝对适用于任何基于 x86 的操作系统,这些操作系统不使用具有多个数据段的分段内存模型用于堆 - 这意味着它肯定适用于 Windows 和 Linux 的 32 位和 64 位模式]。

你可能想用不同的类型运行它 - 请记住差异是“类型的数量,所以如果你把它设为 int *a, *b 将以”四个字节为单位“。你可以制作一个 reinterpret_cast<char*>(a) - reinterpret_cast<char *>(b);

关于c++ - 是否存在与堆内存分配相关的内存开销(例如堆中的标记)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15881170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com