Я сделал следующее выделение памяти
int * a;
a = malloc (5 * sizeof (int));
Есть ли способ просто освободить, скажем, 5-е место этого набора?
т.е. можно сделать бесплатно (а + 4) ??
В настоящее время это дает ошибку ошибки сегментации.
Я сделал следующее выделение памяти
int * a;
a = malloc (5 * sizeof (int));
Есть ли способ просто освободить, скажем, 5-е место этого набора?
т.е. можно сделать бесплатно (а + 4) ??
В настоящее время это дает ошибку ошибки сегментации.
Нет, вы не можете делать free(a+4)
и т. Д.
Почему? Потому что стандарт C запрещает это. Вы должны передать точный указатель, возвращаемый malloc()
, в free()
без какой-либо арифметики указателя.
http://www.kernel.org/doc/man-pages/online/pages/man3/free.3.html
Функция
free()
освобождает пространство памяти, на которое указывает ptr, которое должно было быть возвращено предыдущим вызовомmalloc()
,calloc()
илиrealloc()
.
Почему стандарт запрещает это? Это связано с тем, что некоторые реализации malloc()
хранят информацию заголовка в месте a-4
(или где-то еще), а free()
внутренне считывает ее с помощью арифметики указателя. Если ему дать смещенный указатель, например a+4
, он пропустит информацию заголовка и будет запутан. Ср.
Между прочим, некоторые реализации libc предоставляют нестандартные функции, которые возвращают размер выделенного фрагмента памяти:
Если вам интересно, как они реализованы, и вы заглянете в их исходный код, вы часто обнаружите, что они читают информацию заголовка на a-4
и т. Д.:
Хорошо, вернемся к исходному вопросу. Если вы хотите сократить (или удлинить) блок памяти, выделенный с помощью malloc()
, вы можете использовать realloc()
, как сказал @Gustav. Но если вы хотите удалить несколько байтов из середины фрагмента памяти, вам потребуется перераспределение и копирование вручную. На самом деле realloc()
может внутренне выполнять аналогичную работу, поэтому будьте осторожны с возвращаемым указателем, который может отличаться от исходного.
Если вы хотите освободить только часть пространства, используйте realloc ().