Когда вы звоните realloc()
Вы должны проверить, не завершилась ли функция, прежде чем присваивать возвращаемый указатель указателю, переданному в качестве параметра функции …
Я всегда следовал этому правилу.
Теперь необходимо следовать этому правилу, когда вы точно знаете, что память будет обрезана, а не увеличена?
Я никогда не видел, чтобы это провалилось. Просто подумал, смогу ли я сохранить пару инструкций.
realloc
может по своему усмотрению скопировать блок на новый адрес независимо от того, будет ли новый размер больше или меньше. Это может быть необходимо, если malloc
реализация требует нового выделения, чтобы «сжать» блок памяти (например, если новый размер требует помещения блока памяти в другой пул выделения). Это отмечено в glibc
документация:
В нескольких реализациях размещения иногда для уменьшения размера блока требуется его копирование, поэтому он может потерпеть неудачу, если нет другого доступного пространства.
Поэтому вы должны всегда проверить результат realloc
даже при сокращении. Возможно, что realloc
не удалось сжать блок, потому что он не может одновременно выделить новый, меньший блок.
Даже если ты realloc
(прочитай внимательно перераспределить (3) а про посикс перераспределить пожалуйста) в меньшем размере, базовая реализация делает эквивалент malloc
(нового меньшего размера), а затем memcpy
(из старой в новую зону), затем free
(из старой зоны). Или это может ничего не делать … (например, потому что некоторые грубые malloc
реализации поддерживают ограниченный набор размеров — например, мощность, в два или три раза превышающая мощность двух, а старые и новые требования к размеру соответствуют одному и тому же размеру ….)
Тот malloc
может потерпеть неудачу. Так realloc
все еще может потерпеть неудачу.
На самом деле, я обычно не рекомендую использовать realloc
по этой причине: просто сделайте malloc
, memcpy
, free
сам.
Действительно, динамическая память кучи функционирует как malloc
редко терпят неудачу. Но когда они это сделают, может случиться хаос, если вы не справитесь с этим. В Linux и некоторых других системах Posix вы можете setrlimit (2) с RLIMIT_AS
-например. используя Bash ulimit
встроенный — чтобы снизить пределы для целей тестирования.
Возможно, вы захотите изучить реализации исходного кода C память управления. Например MUSL libc (для Linux) очень читаемый код. В Linux malloc
часто строится выше ММАП (2) (библиотека C может выделить большой кусок памяти, используя mmap
затем управление меньшими используемыми и освобожденными зонами памяти внутри него).