Spec-Zone.ru › C++

std::realloc

Определена в заголовочном файле <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).

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

(до C++26)

Если ptr не является нулевым указателем, а new_size равен нулю, поведение является ошибочным, а эффекты определяются реализацией.

(начиная с C++26)

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

  • Библиотечные версии operator new и operator delete
  • Пользовательские замены глобальных operator new и operator delete
  • std::calloc, std::malloc, std::realloc, std::aligned_alloc(начиная с C++17), std::free

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

(начиная с 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) // this check is not strictly needed,
        {
            std::free(p); // but zero-size realloc is deprecated in 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); // shrink
    assert(buf1[5] == 'f');
    buf1.resize(1024); // grow
    assert(buf1[5] == 'f');
}

См. также

Документация по C для realloc

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

Spec-Zone.ru

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