关于面试问题:我如何编写新的“malloc”和“free”函数?我不认为“使用new和delete”或类似的LocalAlloc/HeapAlloc等功能是可接受的答案。
关于面试问题:我如何编写新的“malloc”和“free”函数?我不认为“使用new和delete”或类似的LocalAlloc/HeapAlloc等功能是可接受的答案。
由于这是一个面试问题,可能没有“正确”答案,他们更关心的是您的思维过程和您对该主题的一般知识。
您应该要求澄清要求,或根据情况给出一系列答案。以下是需要考虑的一些问题:
malloc
函数应该能够从操作系统获得内存,并将其提供给请求动态分配内存的客户端(比如,你的C程序)。为了实现这一点,malloc
库通常需要许多数据结构(根据具体实现而定)——例如,malloc
的实现可能选择使用链表跟踪空闲的内存块。更有效的方法是有一个链表列表,每个列表包含一定大小范围的块。free
时,你的实现(除其他事项外)应该从程序中回收该块,并将其添加到适当的freelists中。如果你想要钩住 malloc()
和 free()
函数调用,可以使用类似以下的方式:
#define malloc(x) your_malloc(x)
#define free(x) your_free(x)
但是,如果你想创建自己的内存分配器,那么你可能需要查看 Kernighan 和 Ritchie 在他们的书 "C程序设计语言 第二版" 中实现的堆分配器之一。它基本上依赖于使用 sbrk()
系统函数来增加进程的数据段的大小。
这取决于需求,例如,如果您想创建嵌入式软件,在运行时有时不允许使用malloc/free或因性能原因。那么您可以创建自己的版本的malloc/free,它不会分配/释放内存,而是从预先分配的堆中获取/返回块。
我想他们可以/应该用另一种方式来表达问题:“malloc和free如何管理堆内存?”
然后,您可以稍微以不同的方式考虑问题-给定一系列值的线性列表,如何划分出列表的块并跟踪它们,如何返回该列表的块,如何管理列表的碎片等。
简而言之,下一个空闲块的地址存储在已分配块旁边的堆中,存储下一个空闲内存块的信息对用户不可见,但仍属于同一堆。这就是为什么超出malloc内存范围可能会完全破坏堆并导致malloc和free等函数崩溃的原因。