Я могу сказать о Linux / glibc.В исходном коде он содержит комментарии вроде этого:
, если n
для меньшего количества байтов, чем уже хранится в p
, недавно неиспользованномпространство отсекается и освобождается, если это возможно.
если вы посмотрите на код glibc, он содержит такие строки:
remainder_size = newsize - nb;
if (remainder_size < MINSIZE) { /* not enough extra to split off */
set_head_size(newp, newsize | (av != &main_arena ? NON_MAIN_ARENA : 0));
set_inuse_bit_at_offset(newp, newsize);
}
else { /* split remainder */
remainder = chunk_at_offset(newp, nb);
set_head_size(newp, nb | (av != &main_arena ? NON_MAIN_ARENA : 0));
set_head(remainder, remainder_size | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
/* Mark remainder as inuse so free() won't complain */
set_inuse_bit_at_offset(remainder, remainder_size);
#ifdef ATOMIC_FASTBINS
_int_free(av, remainder, 1);
#else
_int_free(av, remainder);
#endif
}
nb
- количество байтов, которое вы хотите, newsize
здесь, должно быть вызваноoldsize
.Поэтому он пытается освободить излишки, если это возможно.
О Mac OSX.Точнее о magazine_malloc
, текущей реализации malloc
от Apple.Подробнее см. http://cocoawithlove.com/2010/05/look-at-how-malloc-works-on-mac.html.
realloc
вызывает метод realloc зоны, его текущая реализация, как я вижу, szone_realloc
.Для разных размеров выделения существует разный код, но алгоритм всегда один и тот же:
if (new_good_size <= (old_size >> 1)) {
/*
* Serious shrinkage (more than half). free() the excess.
*/
return tiny_try_shrink_in_place(szone, ptr, old_size, new_good_size);
} else if (new_good_size <= old_size) {
/*
* new_good_size smaller than old_size but not by much (less than half).
* Avoid thrashing at the expense of some wasted storage.
*/
return ptr;
}
Итак, как вы можете видеть, его реализация проверяет, что new_size <= old_size / 2
, и если да, то освобождает память, а если нет, то делаетнет ничего.