Namespaces
Variants

realloc

From cppreference.net
Определено в заголовочном файле <stdlib.h>
void * realloc ( void * ptr, size_t new_size ) ;

Перераспределяет заданную область памяти. Если ptr не равен NULL, он должен быть ранее выделен с помощью 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))) // 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 (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.22.3.5 Функция realloc (стр: 254)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.22.3.5 Функция realloc (стр. 349)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.20.3.4 Функция realloc (стр: 314)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 4.10.3.4 Функция realloc

Смотрите также