#c #arrays #memory-management
#c #массивы #управление памятью
Вопрос:
Допустим, у меня есть массив структур, и я хочу удалить запись, которая имеет структуру с записью, соответствующей некоторым критериям.
Этот массив динамически выделяется с помощью malloc, я сохраняю количество элементов в отдельной переменной.
Как мне приступить к удалению записи?
Я думаю о
for (i = pos; i < arr_len; i ) {
arr[i] = arr[i 1];
}
arr_len--;
Но это оставляет тот же объем памяти для массива, в то время как мне на самом деле нужно меньше и сирота (своего рода) последняя запись.
Является ли выполнение перераспределения в такой ситуации общепринятой практикой? Будет ли realloc выполнять memcpy в этом случае? (сокращение выделяемой памяти на один блок).
Ответ №1:
realloc
все в порядке… но продолжайте читать 🙂
realloc
не приведет к перемещению частей памяти; это может привести к перемещению всего блока. Поэтому вам необходимо скопировать данные перед изменением выделенного размера.
Для перемещения данных memmove
(не memcpy
) является хорошим вариантом: это работает для областей памяти, которые принадлежат одному и тому же объекту. Однако обратите внимание на то, чтобы не выходить за пределы своего массива; как вы делаете в своем коде.
for (i = pos; i < arr_len; i ) {
arr[i] = arr[i 1];
}
arr[i] = arr[i 1];
Попытается получить доступ к элементу, превышающему допустимый размер. Вам нужно
for (i = pos 1; i < arr_len; i ) {
arr[i - 1] = arr[i];
}
При вызове возникают некоторые накладные расходы realloc
. Если ваши структуры невелики и / или они живут недолго, рассмотрите возможность сохранения как количества элементов, так и количества выделенных элементов и перераспределения только для увеличения (когда (element_count 1) > (allocated_count)
).
Если структура большая, также рассмотрите другую структуру данных (возможно, связанный список).
Комментарии:
1. Спасибо за подсказку при доступе к последнему элементу. Я написал этот конкретный случай на бумаге, но все равно умудрился пропустить его, когда ненадолго забыл, что массивы индексируются с 0!
Ответ №2:
Вызов realloc для сокращения выделенной памяти не обязательно будет плохой идеей.
Однако вам, возможно, придется пересмотреть используемую структуру данных. Похоже, что связанный список значительно упростил бы управление памятью и значительно ускорил бы операцию удаления, поскольку для этого не требуется перенос элементов.
Ответ №3:
Здесь было бы уместно использовать realloc. Это не привело бы к выполнению memcpy — это необходимо только тогда, когда размер перераспределения больше и нет места для расширения.