Использование realloc для сокращения выделенной памяти

Простой вопрос о функции realloc в C: Если я использую realloc для сокращения блока памяти, на который указывает указатель, освобождается ли «лишняя» память? Или нужно как-то освободиться вручную?

Например, если я это сделаю

int *myPointer = malloc(100*sizeof(int)); myPointer = realloc(myPointer,50*sizeof(int)); free(myPointer); 

У меня будет утечка памяти?

Нет, у вас не будет утечки памяти. realloc просто отметит остальную «доступную» для будущих операций malloc .

Но вам еще нужно free myPointer позже. В стороне, если вы используете 0 в качестве размера в realloc , он будет иметь такой же эффект, как и на некоторых реализациях . Как сказал Стив Джессоп и Р. .. в комментариях, вы не должны полагаться на это.

Существует определенно не утечка памяти, но любое из по крайней мере 3 вещей может случиться, когда вы вызываете realloc для уменьшения размера:

  1. Реализация разбивает выделенный блок памяти на новую запрошенную длину и освобождает неиспользуемую часть в конце.
  2. Реализация делает новое распределение с новым размером, копирует старое содержимое в новое местоположение и освобождает все прежнее выделение.
  3. Реализация ничего не делает.

Вариант 3 был бы довольно плохой реализацией, но вполне законным; до сих пор нет «утечки памяти», потому что все это будет освобождено, если вы позже позвоните free .

Что касается вариантов 1 и 2, лучше всего зависит от того, пользуетесь ли вы успехом или избегаете fragmentации памяти. Я считаю, что большинство реалий в реальном мире будет склоняться к выполнению варианта 1.

Новый код все еще теряет исходное распределение, если сбой 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) 

В том, как вы дали свой код, да, это может иметь утечку. Идея realloc заключается в том, что он может вернуть вам новое местоположение ваших данных. Как вы делаете это в своем вопросе, вы теряете тот указатель, который посылает вам realloc .

 int *myPointer2 = realloc(myPointer,50*sizeof(int)); assert(myPointer2); myPointer = myPointer2;