realloc

来自cppreference.com
< c‎ | memory
在标头 <stdlib.h> 定义
void *realloc( void *ptr, size_t new_size );

重新分配给定的内存区域。若 ptr 非 NULL,则它必须是之前为 malloc()calloc()realloc() 所分配,并且仍未被 freerealloc 的调用所释放。否则,结果未定义。

重新分配按以下二者之一执行:

a) 可能的话,扩张或收缩 ptr 所指向的现有内存区域。新旧大小中的较小者范围内的区域的内容保持不变。若扩张范围,则数组新增部分的内容是未定义的。
b) 分配一个大小为 new_size 字节的新内存块,并复制大小等于新旧大小中较小者的内存区域,然后释放旧内存块。

若无足够内存,则不释放旧内存块,并返回空指针。

ptrNULL,则行为与调用 malloc(new_size) 相同。

否则,

new_size 为零,则行为是实现定义的(可能返回空指针,该情况下可能或可能不释放旧内存,或可能返回某个不能用于访问存储的非空指针)。这种用法被弃用(经由 C DR 400)。 (C17 起)

(C23 前)

new_size 为零,则行为未定义。

(C23 起)

realloc 是线程安全的:它表现得如同只访问通过其实参可见的内存区域,而非任何静态存储。

先前令 freerealloc 归还一块内存区域的调用,同步于任何分配函数的调用,包括分配相同或部分相同内存区域的 realloc 。这种同步出现于任何解分配函数所做的内存访问后,和任何 realloc 所做内存访问前。所有操作一块特定内存区域的分配及解分配函数拥有单独全序。

(C11 起)

参数

ptr - 指向需要重新分配的内存区域的指针
new_size - 数组的新大小(字节数)

返回值

成功时,返回指向新分配内存的指针。返回的指针必须用 free()realloc() 归还。原指针 ptr 失效,而且任何通过它的访问是未定义行为(即使重分配是就地的)。

失败时,返回空指针。原指针 ptr 保持有效,并需要通过 free()realloc() 归还。

注解

本来(C89 中),增加对零大小的支持是为了容纳这种代码:

OBJ *p = calloc(0, sizeof(OBJ)); // “零长度”占位
/*...*/
while(1) { 
    p = realloc(p, c * sizeof(OBJ)); // 重分配,直至大小稳定
    /* 可能会修改 c 或跳出循环的代码 */
}

示例

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
 
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
 
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // 分配数组
    {
        memcpy(next, pattern, sizeof pattern); // 填充数组
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
 
    // 以如下各值作为新的存储大小,在循环中重新分配。
    const int realloc_size[] = {10, 12, 512, 32768, 65536, 32768};
 
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // 持有模式内容
        }
        else // 若 realloc 失败,则需要释放原指针
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
 
    free(next); // 最后,释放存储
    return EXIT_SUCCESS;
}

可能的输出:

New location: 0x144c010. Size: 8 ints (32 bytes).
Old location: 0x144c010. Size: 10 ints (40 bytes).
New location: 0x144c450. Size: 12 ints (48 bytes).
Old location: 0x144c450. Size: 512 ints (2048 bytes).
Old location: 0x144c450. Size: 32768 ints (131072 bytes).
New location: 0x7f490c5bd010. Size: 65536 ints (262144 bytes).
Old location: 0x7f490c5bd010. Size: 32768 ints (131072 bytes).

引用

  • C23 标准(ISO/IEC 9899:2024):
  • 7.22.3.5 The realloc function (第 TBD 页)
  • C17 标准(ISO/IEC 9899:2018):
  • 7.22.3.5 The realloc function (第 254 页)
  • C11 标准(ISO/IEC 9899:2011):
  • 7.22.3.5 The realloc function (第 349 页)
  • C99 标准(ISO/IEC 9899:1999):
  • 7.20.3.4 The realloc function (第 314 页)
  • C89/C90 标准(ISO/IEC 9899:1990):
  • 4.10.3.4 The realloc function

参阅