Namespaces
Variants

realloc

From cppreference.net
定义于头文件 <stdlib.h>
void * realloc ( void * ptr, size_t new_size ) ;

重新分配给定的内存区域。如果 ptr 不为空,则必须是由 malloc calloc realloc 先前分配且尚未通过调用 free realloc 释放的内存。否则,行为是未定义的。

重新分配通过以下任一方式完成:

a) 在可能的情况下扩展或收缩由 ptr 指向的现有区域。该区域的内容将保持不变,直至新旧尺寸中的较小值。如果区域被扩展,数组新增部分的内容是未定义的。
b) 分配一个大小为 new_size 字节的新内存块,复制相当于新旧尺寸较小值的内存区域,并释放旧内存块。

如果内存不足,旧内存块不会被释放并返回空指针。

如果 ptr NULL ,其行为等同于调用 malloc ( new_size )

否则,

new_size 为零,则行为由实现定义(可能返回空指针(此时旧内存块可能被释放也可能未被释放),或返回可能不可用于访问存储的某非空指针)。 该用法已被弃用(通过 C DR 400 )。 (C17 起)

(C23 前)

new_size 为零,则行为未定义。

(C23 起)

realloc 是线程安全的:其行为表现为仅访问通过其参数可见的内存位置,而不访问任何静态存储。

先前调用 free realloc 来释放内存区域的操作, 同步于 后续调用任何分配函数(包括分配相同或部分相同内存区域的 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 realloc 函数 (p: TBD)
  • C17 标准 (ISO/IEC 9899:2018):
  • 7.22.3.5 realloc 函数 (页: 254)
  • C11 标准 (ISO/IEC 9899:2011):
  • 7.22.3.5 realloc 函数 (p: 349)
  • C99标准(ISO/IEC 9899:1999):
  • 7.20.3.4 realloc函数(页码:314)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 4.10.3.4 realloc 函数

参见

C++ 文档 关于 realloc