Malloc, перераспределить, освободить

#c #malloc #free #dynamic-memory-allocation #realloc

#c #malloc #Бесплатно #динамическое выделение памяти #перераспределение

Вопрос:

 int *p=malloc(20);
 

Теперь куча будет выделять память в 20 байт. И возвращает адрес 1-го байта указателю p. (При условии, что нулевой указатель не возвращается).

Теперь я делаю это,

 int *q=realloc(p, 40);
 

Теперь у них есть следующие возможности:

1]. q = p

2]. q! =p

3]. q= NULL

Забыл о возможности 2 и 3.

Теперь я пишу:

 free(p);
 

Что теперь произойдет?

Станут ли первые 20 байтов свободными, а остальные все равно останутся выделенными, или все 40 байтов станут свободными или что-то еще?

Комментарии:

1. Если realloc возвращает ненулевой указатель, переданный указатель недействителен (т. Е. free d), вам не нужно делать это самостоятельно.

2. Это освободит 40 байт. Просто так получилось, что ему не нужно было ничего перемещать при перераспределении

3. Если q == p не имеет значения, к чему вы переходите free , который понятия не имеет, какую переменную вы использовали, только ее значение. Но это было бы плохой практикой, я считаю, что это академический вопрос.

4. Это не ваш вопрос, но в стандартном C нет способа проверить, если p==q после вызова realloc . Если вызов перераспределения переместил память, то p это недопустимый указатель и p==q может иметь неопределенное поведение (поскольку p и q не указывают на части одного и того же объекта).

5. @2501 да, я прочитал ваш ответ и согласен с ним.

Ответ №1:

Вызов free вызовет неопределенное поведение. Вот рассуждения:

Функция realloc освободит 1 пробел, на который указывает указатель p.

Время жизни 2 объекта, на который указывает p, заканчивается при освобождении.

Функция free получает указатель на освобожденное пространство и вызывает неопределенное поведение 3.

Кроме того, значение указателя p после вызова realloc не определено, и его использование может вызвать неопределенное поведение из-за представлений ловушек.

Другими словами, даже если указатель, возвращенный из realloc, указывает на начало того же пространства, что и указатель p, объект, выделенный realloc, считается новым объектом с новым временем жизни и не может быть освобожден с помощью указателя p .


1 (Цитируется по: ISO / IEC 9899: 201x 7.22.3.5 Функция перераспределения 2)
Функция realloc освобождает старый объект, на который указывает ptr, и возвращает указатель на новый объект, размер которого задан параметром size .

2 (Цитируется по: ISO / IEC 9899: 201x 7.22.3 Функции управления памятью 1)
Время жизни выделенного объекта простирается от выделения до освобождения

3 (Цитируется по: ISO / IEC 9899:201x 7.22.3.3 Свободная функция 2)
В противном случае, если аргумент не соответствует указателю, ранее возвращенному функцией управления памятью, или если пространство было освобождено вызовом free или realloc , поведение не определено.

4 (Цитируется по: ISO / IEC 9899: 201x 6.2.4 Продолжительность хранения объектов 2)
Значение указателя становится неопределенным, когда объект, на который он указывает (или просто мимо), достигает конца своего жизненного цикла.

Ответ №2:

Из справочной страницы malloc / realloc

Функция realloc() пытается изменить размер выделения, на который указывает ptr, на size и возвращает ptr. Если недостаточно места для увеличения выделения памяти, на которое указывает ptr, realloc() создает новое выделение, копирует столько старых данных, на которые указывает ptr, сколько поместится в новое выделение, освобождает старое выделение и возвращает указатель на выделенную память.

Вы должны взглянуть на то, как malloc() free() и realloc() работает. Самый простой способ — это простая реализация.

http://arjunsreedharan.org/post/148675821737/write-a-simple-memory-allocator

Комментарии:

1. Справочные страницы Linux обычно описывают поведение реализации функций в системах Linux, которое может отличаться от стандартной спецификации C и поведения на других платформах.

Ответ №3:

realloc(p,new_size) изменяет размер блока памяти, на который указывает p, который ранее был выделен с помощью вызова malloc или calloc . теперь, если память доступна рядом с ранее выделенной памятью, она возвращает тот же указатель, который мы передаем ей, что и здесь p, поэтому в этом случае, если вы освободите (q), пространство, на которое указывают оба p amp; q, будет удалено.

но если память недоступна рядом с ранее выделенной памятью, то она возвращает другой указатель на вновь выделенное пространство, поэтому в этом случае, если вы освободите (q), вновь выделенное пространство будет удалено

в обоих случаях удаленная память составляет 40 бит