Если у вас есть n
байтов из malloc
выделенной памяти, вы можете перераспределить
m
байтов (где m
< n
) и таким образом отбросить последние нм
байт.
Чтобы отбросить с самого начала, вы можете malloc
новый , буфер меньшего размера и memcpy
нужных вам байтов, а затем освобождение
оригинала.
Последний вариант также доступен с использованием C ++ new
и delete
. Он также может имитировать первый случай realloc
.
Вы можете сделать его короче с помощью realloc (). Я не думаю, что остальное возможно.
Не попробуйте и второстепенное управление памятью. Обычно он умнее вас; -)
Единственное, что вы можете достичь, - это первый сценарий "высвободить" последние 1К
char * foo = malloc(4096);
foo = realloc(foo, 4096-1024);
Однако даже в этом случае НЕТ ГАРАНТИИ, что "foo" останется неизменным. Весь ваш 4K может быть освобожден, а realloc () может переместить вашу память в другое место, тем самым аннулируя любые указатели на нее, которые вы можете удерживать.
Это справедливо как для C, так и для C ++ - однако использование malloc () в C ++ дурной запах кода, и большинство людей ожидают, что вы будете использовать new () для выделения памяти. И память, выделенная с помощью new (), не может быть изменена с помощью realloc () - или, по крайней мере, никаким переносимым способом. Векторы STL были бы гораздо лучшим подходом в C ++
Вы можете использовать realloc (), чтобы уменьшить размер памяти. Обратите внимание, что для некоторых реализаций такой вызов фактически ничего не делает. Вы не можете освободить первый бит блока и сохранить последний.
Если вам нужна такая функциональность, вам следует подумать об использовании более сложной структуры данных. Массив - это не правильный ответ на все проблемы программирования.
http://en.wikipedia.org/wiki/New_ (C% 2B% 2B)
РЕЗЮМЕ: В отличие от перераспределения C, он невозможно напрямую перераспределить память, выделенная с помощью new []. Расширить или уменьшить размер блока, один необходимо выделить новый блок адекватных размер, скопируйте старую память и удалить старый блок. Стандарт C ++ библиотека предоставляет динамический массив, который может быть расширена или уменьшена в std :: vector template.
У вас нет указателя, выделенного на держать 4096 байт », у вас есть указатель на выделенный блок размером 4096 байт.
Если ваш блок был выделен с помощью malloc ()
, realloc ()
позволит вам уменьшить или увеличить размер блока. Однако начальный адрес блока не обязательно останется прежним.
Вы можете ' t изменить начальный адрес блока памяти malloc
'd, что на самом деле и требует ваш второй сценарий. Также нет возможности разделить блок d malloc
.
Это ограничение malloc
/ calloc
/ realloc
/ бесплатный
API - и реализации могут полагаться на эти ограничения (например, ведение бухгалтерской информации о распределении непосредственно перед начальным адресом, что затрудняет перемещение начального адреса).
Теперь malloc
- не единственный доступный распределитель - ваша платформа или библиотеки могут предоставить другие, или вы можете написать свой собственный (который получает память из системы через malloc
, mmap
, VirtualAlloc
или какой-либо другой механизм), а затем передает его вашей программе любым желаемым образом.
Для C ++, если вы выделяете память с помощью std :: malloc
, информация выше применима. Если вы используете new
и delete
, вы выделяете хранилище для объектов и конструируете их, поэтому изменение размера выделенного блока не имеет смысла - объекты в C ++ фиксированного размера.