Удалить выбранное место из набора смежных ячеек памяти

Я сделал следующее выделение памяти
int * a;
a = malloc (5 * sizeof (int));
Есть ли способ просто освободить, скажем, 5-е место этого набора?

т.е. можно сделать бесплатно (а + 4) ??

В настоящее время это дает ошибку ошибки сегментации.


person tss    schedule 08.02.2012    source источник


Ответы (2)


Нет, вы не можете делать free(a+4) и т. Д.

Почему? Потому что стандарт C запрещает это. Вы должны передать точный указатель, возвращаемый malloc(), в free() без какой-либо арифметики указателя.

  • http://www.kernel.org/doc/man-pages/online/pages/man3/free.3.html

    Функция free() освобождает пространство памяти, на которое указывает ptr, которое должно было быть возвращено предыдущим вызовом malloc(), calloc() или realloc().

    • The Linux man pages are not the C standard itself but practically covers equivalent information on the C library functions.

Почему стандарт запрещает это? Это связано с тем, что некоторые реализации malloc() хранят информацию заголовка в месте a-4 (или где-то еще), а free() внутренне считывает ее с помощью арифметики указателя. Если ему дать смещенный указатель, например a+4, он пропустит информацию заголовка и будет запутан. Ср.

Между прочим, некоторые реализации libc предоставляют нестандартные функции, которые возвращают размер выделенного фрагмента памяти:

Если вам интересно, как они реализованы, и вы заглянете в их исходный код, вы часто обнаружите, что они читают информацию заголовка на a-4 и т. Д.:

Хорошо, вернемся к исходному вопросу. Если вы хотите сократить (или удлинить) блок памяти, выделенный с помощью malloc(), вы можете использовать realloc(), как сказал @Gustav. Но если вы хотите удалить несколько байтов из середины фрагмента памяти, вам потребуется перераспределение и копирование вручную. На самом деле realloc() может внутренне выполнять аналогичную работу, поэтому будьте осторожны с возвращаемым указателем, который может отличаться от исходного.

person nodakai    schedule 08.02.2012

Если вы хотите освободить только часть пространства, используйте realloc ().

person Gustav Larsson    schedule 08.02.2012