命名空间
变体
操作

realloc

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

重新分配给定的内存区域。如果 ptr 不是 NULL,则它必须是之前使用 malloccallocrealloc 分配的,并且尚未通过调用 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 - 数组的新大小(以字节为单位)

[编辑] 返回值

成功时,返回指向新分配内存开头的指针。为了避免内存泄漏,必须使用 freerealloc 释放返回的指针。原始指针 ptr 已失效,对它的任何访问都是未定义的行为(即使重新分配是就地进行的)。

失败时,返回空指针。原始指针 ptr 仍然有效,可能需要使用 freerealloc 释放。

[编辑] 备注

最初(在 C89 中),添加了对零大小的支持以适应以下代码:

OBJ *p = calloc(0, sizeof(OBJ)); // "zero-length" placeholder
/*...*/
while (1)
{
    p = realloc(p, c * sizeof(OBJ)); // reallocations until size settles
    /* code that may change c or break out of loop */
}

[编辑] 示例

#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))) // allocates an array
    {
        memcpy(next, pattern, sizeof pattern); // fills the array
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
 
    // Reallocate in cycle using the following values as a new storage size.
    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));  // is pattern held
        }
        else // if realloc failed, the original pointer needs to be freed
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
 
    free(next); // finally, frees the storage
    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 函数 (p: 254)
  • C11 标准 (ISO/IEC 9899:2011)
  • 7.22.3.5 realloc 函数 (p: 349)
  • C99 标准 (ISO/IEC 9899:1999)
  • 7.20.3.4 realloc 函数 (p: 314)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 4.10.3.4 realloc 函数

[编辑] 另请参见

C++ 文档 for realloc