2011-04-06 3 views
1

Допустим, у меня есть массив структур, и я хочу удалить запись, в которой есть структура с записью, соответствующей некоторым критериям.Удаление динамически выделенных элементов массива в C

Этот массив динамически выделяется с помощью malloc, я сохраняю число элементов в отдельной переменной.

Как мне удалить эту запись?

Я имею в виду

for (i = pos; i < arr_len; i++) { 
    arr[i] = arr[i+1]; 
} 
arr_len--; 

Но это оставляет такой же объем памяти для массива в то время как я на самом деле нужно меньше и сироту (вроде) последней записи.

Выдает ли realloc в такой ситуации общепринятую практику? Будет ли realloc делать memcpy в этом случае? (сокращение выделенной памяти на один блок).

ответ

4

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. Если ваши структуры невелики и/или они живут только ненадолго, подумайте о том, чтобы сохранить как счетчик элементов, так и выделенный счетчик и только realloc для увеличения (когда (element_count + 1) > (allocated_count)).


Если структура большая, рассмотрите другую структуру данных (возможно, связанный список).

+0

Спасибо за улов на последнем доступе элемента. Я написал этот конкретный случай на бумаге, но все же сумел пропустить его, когда вкратце забыл, что массивы индексируются с 0! – Karolis

0

Использование realloc было бы уместным здесь. Это не будет делать memcpy - это необходимо только тогда, когда размер realloc больше, и нет места для расширения.

1

Вызов realloc для сокращения выделенной памяти не обязательно будет плохой идеей.

Однако, возможно, вам придется пересмотреть структуру данных, которые вы используете. Похоже, что связанный список упростит управление памятью и сделает операцию удаления намного быстрее, поскольку она не требует смещения элементов.

Смежные вопросы