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).
Если new_size равно нулю, поведение определяется реализацией: может быть возвращён нулевой указатель (в этом случае старый блок памяти может быть или не быть освобождён) или какой-либо ненулевой указатель, который может не использоваться для доступа к памяти. Такое использование устарело (через C DR 400).(с C++20)
| Следующие функции должны быть потокобезопасными:
Вызовы этих функций, которые выделяют или освобождают определённый блок памяти, происходят в едином общем порядке, и каждый такой вызов освобождения предшествует следующему выделению (если таковое есть) в этом порядке. | (с 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/w/cpp/memory/c/realloc