Использование realloc для сокращения выделенной памяти
Простой вопрос о функции realloc в C:
Если я использую realloc для сокращения блока памяти, на который указывает указатель, освобождается ли "лишняя" память? Или нужно как-то освободиться вручную?
Например, если я делаю
int *myPointer = malloc(100*sizeof(int));
myPointer = realloc(myPointer,50*sizeof(int));
free(myPointer);
У меня будет утечка памяти?
Ответы
Ответ 1
Нет, у вас не будет утечки памяти. realloc
будет просто отмечать остальную "доступную" для будущих операций malloc
.
Но вам все равно придется free
myPointer
позже. В стороне, если вы используете 0
как размер в realloc
, он будет иметь тот же эффект, что и free
для некоторых реализаций. Как сказал Стив Джессоп и Р... в комментариях, вы не должны полагаться на это.
Ответ 2
Существует определенно не утечка памяти, но любое из по меньшей мере 3 вещей может случиться, когда вы вызываете realloc
для уменьшения размера:
- Реализация разбивает выделенный блок памяти на новую запрашиваемую длину и освобождает неиспользуемую часть в конце.
- Реализация создает новое распределение с новым размером, копирует старое содержимое в новое место и освобождает все прежнее выделение.
- Реализация ничего не делает.
Вариант 3 будет довольно плохой реализацией, но вполне законным; по-прежнему нет "утечки памяти", потому что все это будет освобождено, если вы позже назовете free
на нем.
Что касается опций 1 и 2, то лучше всего зависит от того, одобряете ли вы производительность или избегаете фрагментации памяти. Я считаю, что большинство реализаций в реальном мире будут склоняться к выполнению варианта 1.
Ответ 3
Новый код все еще теряет исходное распределение, если сбой realloc. Я ожидаю, что большинство реализаций никогда не перестанут сокращать блок, но это разрешено. Правильный способ вызова realloc, независимо от того, растет или сокращается блок, void * tmp = realloc (myPointer, 50 * sizeof (int)); if (! tmp) {/* обрабатывать ошибку как-то. myPointer все еще указывает на старый блок, который по-прежнему выделяется */} myPointer = tmp;. - Стив Джессод 48 мин назад
Эй, я не мог понять, как ответить на ваш комментарий, извините.
Нужно ли использовать tmp для типа myPointer? В этом случае мне нужно написать
myPointer = (int*)tmp
Кроме того, в этом случае, когда я это делаю бесплатно (myPointer)
Память, на которую указывает tmp, также будет освобождена, верно? Поэтому не нужно делать
free(myPointer)
free(tmp)
Ответ 4
Таким образом, вы дали свой код, да, это может иметь утечку. Идея realloc
заключается в том, что она может вернуть вам новое местоположение ваших данных. Как вы делаете это в своем вопросе, вы теряете тот указатель, который отправляет realloc
.
int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2);
myPointer = myPointer2;