Spec-Zone.ru › C

realloc

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

Перевыделяет указанную область памяти. Если ptr не равно NULL, оно должно быть ранее выделено функцией malloc, calloc или realloc и ещё не освобождено с помощью вызова free или realloc. В противном случае результаты неопределённы.

Перевыделение выполняется следующим образом:

a) расширение или сжатие существующей области, на которую указывает ptr, если это возможно. Содержимое области остаётся неизменным до меньшего из нового и старого размеров. Если область расширяется, содержимое новой части массива неопределено.
b) выделение нового блока памяти размером new_size байт, копирование области памяти размером, равным меньшему из нового и старого размеров, и освобождение старого блока.

Если памяти недостаточно, старый блок памяти не освобождается, и возвращается указатель null.

Если ptr равно NULL, поведение такое же, как при вызове malloc(new_size).

В противном случае,

если new_size равно нулю, поведение определено реализацией (может быть возвращён указатель null (в этом случае старый блок памяти может быть или не быть освобождён), или может быть возвращён некоторый ненулевой указатель, который может не использоваться для доступа к хранилищу). Такое использование устарело (через C DR 400).(с C17)

(до C23)

если new_size равно нулю, поведение неопределённо.

(с C23)

realloc является потокобезопасным: оно ведёт себя так, как будто оно обращается только к расположениям памяти, видимым через свой аргумент, а не к любому статическому хранилищу.

Предыдущий вызов free или realloc освобождающий область памяти, _синхронизируется_ с вызовом любой функции выделения памяти, включая realloc , выделяющей ту же или часть той же области памяти. Эта синхронизация происходит после любого доступа к памяти функцией освобождения и перед любым доступом к памяти функцией realloc. Существует единый общий порядок всех функций выделения и освобождения, действующих на каждой конкретной области памяти.

(с C11)

Параметры

ptr - указатель на область памяти, подлежащую перевыделению
new_size - новый размер массива в байтах

Возвращаемое значение

При успехе возвращает указатель на начало вновь выделенной памяти. Для предотвращения утечки памяти возвращённый указатель необходимо освободить с помощью free или realloc . Исходный указатель ptr считается недействительным, и любой доступ к нему является неопределённым поведением (даже если перевыделение было выполнено на месте).

При неудаче возвращает указатель null. Исходный указатель ptr остаётся действительным и может потребоваться освободить с помощью free или realloc.

Примечания

Изначально (в 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:2023):
    • 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++ для realloc

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/memory/realloc

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API