c++分配的字节比要求的多

C++ allocates more bytes than asked?

本文关键字:字节 分配 c++      更新时间:2023-10-16
int main(int argc, const char* argv[])
{
    for(unsigned int i = 0; i < 10000000; i++)
        char *c = new char;
    cin.get();
}

在上面的代码中,为什么我的程序使用471MB内存而不是像人们期望的那样使用10MB内存?

RAM的分配来自运行时库和操作系统的共同努力。为了识别示例代码请求的一个字节,有一些结构可以将此内存识别到运行时。它有时是一个双链表,但它由操作系统和运行时实现定义。

你可以这样类比:如果你有一个链表容器,你感兴趣的只是你在每个链接中放置的东西,但是为了维护链表,容器必须有指向容器中其他链接的指针。

如果您使用调试器或其他调试工具来跟踪内存,这些结构可能更大,使每个分配的成本更高。

RAM通常不会从数组中分配,但是可以重载new操作符来改变分配行为。可以从一个数组(在您的示例中是一个大数组)中专门分配,以便分配表现为您所期望的,并且在某些应用程序中,这是控制内存和提高性能的特定策略(尽管细节通常比简单的说明更复杂)。

分配不仅包含已分配的内存本身,还至少包含一个字,告诉delete它必须释放多少内存;此外,这是一个必须正确对齐的数字,因此在分配的字符之后将有一定的填充,以确保下一个块正确对齐。在64位机器上,这意味着每次分配至少16字节(8字节保存大小,1字节保存字符,7字节填充以确保正确对齐)。

然而,很可能这不是存储的唯一数据;为了帮助内存分配器找到空闲内存,可能会存储额外的数据;如果假设数据由三个指针组成,则每次分配的总字节数为40字节,这与您的数据非常匹配。

还请注意,分配器也会从操作系统请求比实际分配所需更多的内存,因此它不需要为每一个小分配做一个昂贵的操作系统调用。也就是说,运行时库从操作系统中分配较大的内存块,然后将其分成较小的块用于程序的分配。因此,通常会从操作系统中分配一些内存(从而显示在任务管理器中),但尚未分配给程序中的某个对象。