operator new 如何知道内存已分配[重复]

Posted

技术标签:

【中文标题】operator new 如何知道内存已分配[重复]【英文标题】:How operator new knows that memory is allocated [duplicate] 【发布时间】:2015-05-01 10:30:57 【问题描述】:

在C++中,可以operator new如何保存一块内存被分配的信息? AFAIK,它不能在恒定时间内工作,并且必须在堆中搜索空闲内存。或者,也许不是关于 C++,而是关于 OS?

附:不知道是不是标准规定的,是OS管理的还是C++管理的,具体怎么实现呢?

【问题讨论】:

new 如何分配内存是编译器供应商的实现细节。一些new 实现在内部使用malloc(),有些则没有。但很少有人直接进入操作系统,通常在两者之间有一个运行时库,管理内存分配(除其他外)。代码不应该关心方式或其他方式。它要求编译器new 一些内存,并得到一个指针作为回报。如何管理内存由编译器决定。 我认为 C++ 语言标准没有定义它,但最简单的方法是多分配几个字节,并在其中存储下一个可用内存块的地址(所以堆通常实现为链表)。 由操作系统完成的内存管理。 简短的回答是它很可能不会这样做。内存管理器主要跟踪可用于分配的内存块。当前分配的块只是从其可用块列表中删除。当您调用delete 时,该块被添加回空闲列表。 @Juergen 操作系统没有理由不能管理小内存块;我实际上使用了一种 C 实现,其中 mallocfree 只是对操作系统的请求。然而,大多数人不能非常有效地做到这一点,因此出于效率原因,mallocfree 通常从大的进程内存块中分配。除非你要求很大的东西; malloc 直接进入操作系统获取几兆的情况并不少见。 【参考方案1】:

new 维护一个数据结构来跟踪单独分配的块。有很多方法可以做到这一点。通常,使用某种链表。

这里有一个small article 来说明这一点。

【讨论】:

【参考方案2】:

new 通常是在 malloc/free 的基础上实现的。

malloc/free 是如何实现的?答案是:这取决于实施。令人惊讶的是:Malloc 通常根本不跟踪分配的块!唯一的事情,malloc 大部分时间都在做,就是在分配的块“之前”添加一些包含块大小的信息。这意味着,当您分配 40 个字节时,它将分配 44 个字节(在 32 位机器上)并在前 4 个字节中写入大小。它将这个chunk+4的地址返回给你。

Malloc/free 跟踪一个空闲列表。 freelist 是尚未(尚未)返回给操作系统的已释放内存块的列表。 Malloc 搜索空闲列表,当需要一个新块并且有合适的块可用时使用它。

但我在这里给出了关于 malloc/free 的更令人筋疲力尽的答案: How do malloc() and free() work?

一个附加信息:

许多分配器不跟踪分配的块这一事实的一个含义:当您通过 free 或 delete 返回内存并传入一个以前未分配的指针时,您将破坏您的堆,因为系统不是能够检查指针是否有效。关于它的真正丑陋的事情是,在这种情况下,您的程序不会立即转储,而是在错误原因发生后的任何时间......因此这个错误真的很难找到。这就是 C/C++ 中的内存处理如此困难的原因之一!

【讨论】:

"Malloc 通常根本不跟踪分配的块!"但是free()不取block的大小,怎么知道呢? 好的,没错。我忘记了这一点 - 并将添加我的答案。 至少有一个广泛的实现将分配块和空闲块放在同一个列表中。该列表是有序的,这使得合并空闲块(直到在malloc 中的搜索到达空闲块时才发生)非常简单。 (我怀疑现代实现要复杂得多,对小块进行了优化等) @JamesKanze:我不熟悉所有的实现,当然还有最新的实现,我不知道。这就是原因,我试着认真回答。还具有特殊的安全功能,包括今天,当然总是有新的发展。但作为开发人员,最好不要依赖于这样一个事实,malloc/new 会保存损坏的指针。 但即使实现将分配的块保留在列表中也是如此。唯一的问题是您正在描述一种特定的可能实现(即使我从未见过它也可能实际使用过)。还有很多很多,我怀疑你描述的那个不是特别常见。【参考方案3】:

没有简单、标准的答案。 operator new/operator delete 的大多数实现最终转发到malloc/free,但是有一个 许多不同的算法可以用于这些。唯一的就是 或多或少普遍的是分配通常会分配一点 超过请求,并使用额外的内存(通常在地址前面 实际返回)来维护一些额外的信息:要么是实际 分配的大小或指向块末尾的指针(或下一个块的开头 堵塞)。除了一些算法将保持相同大小的分配 在一起,并且能够从地址确定大小。没有 您的问题的单一答案。

【讨论】:

以上是关于operator new 如何知道内存已分配[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 operator new/malloc 分配的内存块能否在程序执行结束后持续存在? [复制]

C++ 内存分配(new,operator new)详解

转C++ 内存分配(new,operator new)详解

C++ 内存分配(new,operator new)详解

C++ 内存分配(new,operator new)详解

c++内存分配(new,operator new)详解