realloc函数在处理内存不足时的处理方式是如何的?

30
如果原始位置没有足够的内存可用:
  • 它会分配多个内存块,并返回指向其中一个块的指针,所有块在内部相互链接吗?
  • 原始区域会被复制到一个有足够内存可用的新位置吗?
  • 会返回指向新地址的指针,同时释放旧位置的内存吗?
realloc是否与编译器/操作系统相关?
3个回答

30

realloc尝试在堆上的空闲内存足够时扩展可用内存范围。如果不足,则相当于使用malloc分配一个新大小的块,将内容使用memcpy复制到其中,然后free释放旧块。这独立于操作系统和编译器,并取决于您链接的libc的实现。

类似的,mremap/MREMAP_MAYMOVE(现代Linux可用)将尝试通过所请求的大小来扩展虚拟映射。如果不可能,则会将您的映射移动到有足够虚拟内存空间的新虚拟地址,然后扩展您的映射。如果您经常调整大型映射的大小,则此过程非常快速,因为无需进行物理复制。


1
实际上,如果size参数比之前的调用小,realloc也可以减少内存范围。 - calandoa

20

realloc() 的实现可能类似于以下内容:

void * realloc(void *ptr, size_t size)
{
    // realloc() on a NULL pointer is the same as malloc().
    if (ptr == NULL)
        return malloc(size);

    size_t oldsize = malloc_getsize(ptr);

    // Are we shrinking an allocation? That's easy.
    if (size < oldsize) {
        malloc_setsize(ptr, size);
        return ptr;
    }

    // Can we grow this allocation in place?
    if (malloc_can_grow(ptr, size)) {
        malloc_setsize(ptr, size);
        return ptr;
    }

    // Create a new allocation, move the data there, and free the old one.
    void *newptr = malloc(size);
    if (newptr == NULL)
        return NULL;
    memcpy(newptr, ptr, oldsize);
    free(ptr);
    return newptr;
}

请注意,我在这里调用了几个以malloc_开头的函数。据我所知,这些函数实际上在任何实现中都不存在;它们旨在作为分配器内部实际执行这些任务的占位符。
由于realloc()的实现取决于这些内部工具,因此其实现取决于操作系统。但是,realloc()接口是通用的。

5

如果旧指针不能在原地调整大小,则会分配一个新指针,将内容复制并释放旧指针。


旧指针不能在原地调整大小,您能解释一下吗? - Yanjan. Kaf.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接