Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 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;