std::realloc
Определена в заголовочном файле <cstdlib> | ||
|---|---|---|
void* realloc( void* ptr, std::size_t new_size ); |
Перераспределяет заданную область памяти (объекты неявно создаются в целевой области). Память должна быть ранее выделена с помощью std::malloc, std::calloc или std::realloc и ещё не освобождена с помощью std::free, в противном случае поведение не определено.
Перераспределение выполняется одним из следующих способов:
ptr, если это возможно. Содержимое области остаётся неизменным до меньшего из нового и старого размеров. Если область расширяется, содержимое новой части массива не определено.new_size байт, в него копируется область памяти размером, равным меньшему из нового и старого размеров, а старый блок освобождается.Если памяти недостаточно, старый блок памяти не освобождается, а возвращается нулевой указатель.
Если ptr — нулевой указатель, поведение такое же, как при вызове std::malloc(new_size).
| Если | (до C++26) |
| Если | (начиная с C++26) |
| Следующие функции должны быть потокобезопасными:
Вызовы этих функций, выделяющие или освобождающие определённую область хранилища, образуют единый полный порядок, и каждый такой вызов освобождения предшествует по отношению 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