Использование delete[] для массива, переданного в качестве аргумента

#c #realloc

#c #перераспределить

Вопрос:

Итак, предположим, что вы хотели создать функцию перераспределения на C . Я полагаю, что это может работать примерно так:

 template<typename T>
void realloc(T** arr, int size, int original_size){
  T *newArr = new T[size];
  for(int i = 0; i<original_size;i  )
    newArr[i] = (*arr)[i];
  delete[] *arr;
  *arr = newArr;
}
  

Теперь мой вопрос в том, правильно ли использовать delete[] здесь? Насколько я знаю, объем выделенной памяти отслеживается во время выполнения, поэтому C знает, сколько удалять. Сохраняется ли это при передаче таким образом или есть более эффективные способы сделать это?

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

1. В C нет сборщика мусора

2. Черт возьми, по какой-то причине я думал, что было. Я отредактирую вопрос

3. Код выглядит нормально. Конечно, вы получаете что-то подобное бесплатно (и с превосходной реализацией), если используете std::vector .

4. Единственный раз, когда это допустимо использовать, delete [] *arr это если *arr это указатель, который является результатом new [] выражения (или null, для которого delete [] не имеет никакого эффекта). Если вызывающий объект передает такой аргумент, который *arr не является результатом такого выражения, поведение не определено. Кроме того, в вашем коде, если original_size превышает фактический размер, выделенный для *arr или если original_size > size , поведение вашего цикла не определено (доступ после окончания выделенной памяти). В конце концов, вам было бы лучше использовать std::vector — который заботится о чистом изменении размера.

5. Использование интеллектуальных указателей или контейнеров сэкономило бы много усилий, чем ручная обработка памяти.

Ответ №1:

Теперь мой вопрос в том, правильно ли использовать delete [] здесь?

Да, при условии, что *arr было выделено с помощью new[] .

Насколько я знаю, объем выделенной памяти отслеживается во время выполнения, поэтому C знает, сколько удалять. Сохраняется ли это при передаче его таким образом […]?

Я не совсем уверен, что вы здесь имеете в виду. Среда выполнения отслеживает распределение памяти, да. Но вы должны четко указывать, что нужно использовать delete[] для массивов (типа new int[10]) и delete для не массивов (типа new MyClass() ).

или есть лучшие способы сделать это?

Следует избегать использования необработанных указателей, даже голых new , что в наши дни считается плохой практикой. Интеллектуальные указатели и подобные им STL-контейнеры std::vector являются превосходными альтернативами практически для любого сценария.

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

1. Извините, я не имел в виду компилятор. Допустил ошибку при написании. Спасибо за разъяснение

2. @Buffer да, исправлена цитата 🙂

3. К вашему сведению, это «в наши дни» 🙂

4. @AsteroidsWithWings Ах, спасибо. Я не являюсь носителем английского языка 🙂 Но, похоже, на самом деле между ними есть разница.

5. Разница между «этими» и «теми» заключается в расстоянии (по некоторой мере) от говорящего. Таким образом, «эти дни» буквально относятся к «временному интервалу или набору дней, который включает сегодняшний день», тогда как «те дни» относятся к «временному интервалу или набору дней, который исключает сегодняшний день».