std::realloc
| Определено в заголовочном файле <cstdlib>
|
||
| void* realloc( void* ptr, std::size_t new_size ); |
||
Перераспределяет данную область памяти. Она должна быть выделена с помощью std::malloc(), std::calloc() или std::realloc(), но ещё не очищена с помощью std::free(), иначе результат может быть не определён.
Перераспределение может быть выполнено одним из двух способов:
ptr. Содержимое этой области останется нетронутым для первых new_size байт памяти. Если область расширяется, то содержимое добавляемой части памяти не определено.new_size байт, копирование туда первых new_size байт старой области и освобождение старого блока памяти.Если памяти не хватит, то старый блок памяти не удалится и нулевой указатель будет возвращён.
Если ptr равен NULL, то поведение этой функции аналогично вызову std::malloc(new_size).
Если new_size равно нулю, то поведение функции зависит от реализации (может как возвратиться как нулевой указатель, так и ненулевой указатель, не пригодный для хранения данных).
Содержание |
[править] Параметры
| ptr | — | Указатель на область памяти, которую необходимо перераспределить. |
| new_size | — | Новый размер массива. |
[править] Возвращаемое значение
Если перераспределение успешно, то возвращается указатель на начало выделенной памяти. Область памяти с возвращенным указателем должна быть очищена с помощью std::free(), а блок памяти, доступный по исходному указателю ptr, освобождается, таким образом обращение к нему приведёт к неопределённому поведению (даже если память перераспределится в ту же область).
Если произойдёт ошибка, то возвратится нулевой указатель. Исходный указатель ptr останется корректным и его потом необходимо будет очистить с помощью std::free().
[править] Примечание
Так как перераспределение может вызвать побайтовое копирование (без разницы происходит увеличение или уменьшение выделенной области), только к объектам TriviallyCopyable типов возможно безопасно обратиться после применения к ним realloc.
Некоторые нестандартные библиотеки определяют такие типы как "BitwiseMovable" или "Relocatable", для которых необходимо, чтобы они не содержали:
- Внешних ссылок (например, узел списка или дерева, который хранит ссылку на другой элемент)
- Внутренних ссылок (например, член, который является указателем на другой член объекта).
К объектам таких типов можно будет безопасно обращаться после того, как их хранилище переместилось, даже если их конструктор копирования не является стандартным.
[править] Например
#include <cstdlib> #include <new> #include <cassert> 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); // так как 0-байтовое перераспределение устарело в Си 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'); }
[править] См. также
| Документация по C для realloc
|

