Malloc() - 新页面请求或重新循环先前分配的内存之间的决定

时间:2015-06-09 21:26:59

标签: c linux memory malloc glibc

我对C'相对较新。这个疑问一直困扰着我好几天。希望你们能来救援!

我似乎无法理解malloc()何时以及何时决定回收先前分配的内存,现在从同一进程中释放并请求操作系统获取新页面。你能帮我理解潜在的机制吗?非常感谢!

以下是我的测试代码示例:

#include <stdio.h>
#include <stdlib.h>

int main(){

    char *ptr;
    int mem_size1, mem_size2; 
    printf("\nEnter the size (in bytes) for malloc: ");
    scanf("%d", &mem_size1);
    ptr = (char *)malloc(mem_size1);
    if (ptr!=NULL){
        printf("\nAllocated %d bytes at addr=%p\n\n", mem_size1, ptr);
    }
    free(ptr); //free-up the addresses for re-allocation

    printf("\nAgain, enter the size (in bytes) for malloc: ");
    scanf("%d", &mem_size2);
    ptr = (char *)malloc(sizeof(char)*mem_size2);
    if (ptr!=NULL){
        //check if the memory address is being re-allocated
        printf("\nAllocated %d bytes at addr=%p\n\n", mem_size2, ptr);
    }
    free(ptr); //free-up the addresses for re-allocation
return(0);
}

这是我的输出序列:

情况I:初始分配大小为10个字节,重新分配大小为24个字节

Enter the size (in bytes) for malloc: 10

Allocated 10 bytes at addr=9C7010 

Again, enter the size (in bytes) for malloc: 24

Allocated 24 bytes at addr=9C7010 //Same address space is being reused

情况II:初始分配大小为10个字节,重新分配大小为25个字节

 Enter the size (in bytes) for malloc: 10

 Allocated 10 bytes at addr=23F6010

 Again, enter the size (in bytes) for malloc: 25

 Allocated 25 bytes at addr=23F6030 //Different address space

我使用的是64位Linux操作系统,系统页面大小为4096B。

因此,我不明白为什么即使重新分配请求仅超过一个字节,情况II中的malloc()也会请求来自OS的全新地址空间。谢谢!

2 个答案:

答案 0 :(得分:1)

它取决于 malloc 实现,但其中一种技术涉及分配堆空间并具有指向堆顶部的指针。返回的内存必须是连续的,并且可以在需要时增加堆的大小。

来自this malloc implementation based on sbrk syscall

  

操作系统为进程保留堆栈和堆空间,sbrk让我们   操纵堆。 sbrk(0)返回指向当前顶部的指针   堆。 sbrk(foo)通过foo递增堆大小并返回a   指向堆的上一个顶部的指针。

如果释放指针,你可以在连续空间的中间获得一个自由空间,在这种情况下,malloc只是将空间标记为空闲,然后在下一个分配中,malloc找到下一个足够大的空间来容纳你问的分配:

  

对于我们的malloc,我们希望尽可能重用免费空间,   在我们无法重用现有空间时分配空间。鉴于我们   有这个链表结构,检查我们是否有一个空闲块和   返回它是直截了当的。当我们得到一些大小的请求时,   我们遍历链接列表以查看是否存在空闲块   这够大了。

     

如果我们找不到空闲块,我们将不得不从操作系统请求空间   使用sbrk并将我们的新块添加到链表的末尾。

答案 1 :(得分:0)

malloc是否从堆中返回相同的地址,因为对malloc的不同调用有多个标准,并且可能因同一程序的不同执行而异。

1) the first malloc'd memory must be passed to free() 
   before the second call to malloc

2) (here the user has no control)  
   the algorithm used by the malloc function
   can be implemented in several different ways.
   -some will keep re-allocating from the same memory address as long as space is available
   -some will cycle through a pre-allocated set of memory buffers
   -some use a randomizer for where in memory to start allocating
   -etc

一个细节,大多数malloc稍微超过分配。 I.E.实际分配比实际要求的更多(不依赖于这个'特征',因为这样做会导致未定义的行为,并且/将导致seg故障事件。)

在OPs的情况下,我怀疑使用的malloc函数预先分配了要分配的区域表。恰好在24到25之间的表格大小之间存在中断