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

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

например, если я делаю

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

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

4 ответов


нет, у вас не будет утечки памяти. realloc просто отметит остальные "доступные" для будущего malloc операции.

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


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

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

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

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


новый код все еще пропускает исходное распределение, если перераспределение не удается. Я ожидаю, что большинство реализаций никогда не смогут уменьшить блок, но это разрешено. Правильный способ вызова 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;