Пространства имён
Варианты
Действия

std::realloc

Материал из cppreference.com
< cpp‎ | memory‎ | c
 
 
 
Динамическое управление памятью
Низкоуровневое управление памятью
Аллокаторы
allocator
allocator_traits(C++11)
allocator_arg_t(C++11)
allocator_arg(C++11)
uses_allocator(C++11)
scoped_allocator_adaptor(C++11)
Неинициализированные хранилища
uninitialized_copy
uninitialized_copy_n(C++11)
uninitialized_fill
uninitialized_fill_n
raw_storage_iterator
get_temporary_buffer
return_temporary_buffer
Умные указатели
unique_ptr(C++11)
shared_ptr(C++11)
weak_ptr(C++11)
auto_ptr(устарело)
owner_less(C++11)
enable_shared_from_this(C++11)
bad_weak_ptr(C++11)
default_delete(C++11)
Поддержка сборки мусора
declare_reachable(C++11)
undeclare_reachable(C++11)
declare_no_pointers(C++11)
undeclare_no_pointers(C++11)
pointer_safety(C++11)
get_pointer_safety(C++11)
Разное
pointer_traits(C++11)
addressof(C++11)
align(C++11)
Библиотека C
realloc
free
 
Определено в заголовочном файле <cstdlib>
void* realloc( void* ptr, std::size_t new_size );

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

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

a) По возможности происходит расширение или усечение имеющейся области с указателем ptr. Содержимое этой области останется нетронутым для первых new_size байт памяти. Если область расширяется, то содержимое добавляемой части памяти не определено.
b) Выделение новой области памяти размером в 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 documentation for realloc