Namespaces
Variants

std:: realloc

From cppreference.net
< cpp ‎ | memory ‎ | c
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Определено в заголовочном файле <cstdlib>
void * realloc ( void * ptr, std:: size_t new_size ) ;

Перераспределяет заданную область памяти ( неявно создавая объекты в области назначения). Она должна быть ранее выделена с помощью std::malloc , std::calloc или std::realloc и еще не освобождена с помощью std::free , в противном случае результат не определен.

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

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

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

Если ptr является нулевым указателем, поведение эквивалентно вызову std:: malloc ( new_size ) .

Если new_size равен нулю, поведение определяется реализацией: может быть возвращен нулевой указатель (в этом случае старый блок памяти может быть освобожден или не освобожден) или может быть возвращен некоторый ненулевой указатель, который нельзя использовать для доступа к памяти. Такое использование объявлено устаревшим (через C DR 400 ). (начиная с C++20)

Следующие функции должны быть потокобезопасными:

Вызовы этих функций, которые выделяют или освобождают определенную единицу памяти, происходят в едином общем порядке, и каждый такой вызов освобождения happens-before следующего выделения (если таковое имеется) в этом порядке.

(since C++11)

Содержание

Параметры

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

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

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

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

Примечания

Поскольку перераспределение может включать побайтовое копирование (независимо от того, расширяется или сжимается область), необходимо (но недостаточно), чтобы эти объекты были типа TriviallyCopyable .

Некоторые нестандартные библиотеки определяют трейт типа "BitwiseMovable" или "Relocatable", который описывает тип, не имеющий:

  • внешние ссылки (например, узлы списка или дерева, содержащие ссылку на другой элемент), и
  • внутренние ссылки (например, указатель-член, который может содержать адрес другого члена).

Объекты такого типа могут быть доступны после перераспределения их хранилища, даже если их конструкторы копирования не являются тривиальными.

Пример

#include <cassert>
#include <cstdlib>
#include <new>
class MallocDynamicBuffer
{
    char* p;
public:
    explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr)
    {
        resize(initial);
    }
    ~MallocDynamicBuffer() { std::free(p); }
    void resize(std::size_t newSize)
    {
        if (newSize == 0) // эта проверка не строго необходима,
        {
            std::free(p); // но realloc нулевого размера устарел в C
            p = nullptr;
        }
        else
        {
            if (void* mem = std::realloc(p, newSize))
                p = static_cast<char*>(mem);
            else
                throw std::bad_alloc();
        }
    }
    char& operator[](size_t n) { return p[n]; }
    char operator[](size_t n) const { return p[n]; }
};
int main()
{
    MallocDynamicBuffer buf1(1024);
    buf1[5] = 'f';
    buf1.resize(10); // уменьшение
    assert(buf1[5] == 'f');
    buf1.resize(1024); // увеличение
    assert(buf1[5] == 'f');
}

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