Как распределяется и освобождается * массив * памяти в C и C ++? - PullRequest
4 голосов
/ 20 августа 2009

Мой вопрос, в частности, касается массивов, , а не объектов.

Есть несколько вопросов по SO о malloc() / free() против new / delete, но все они сосредоточены на различиях в том, как они используются. Я понимаю, как они используются, но я не понимаю, какие основные различия вызывают различия в использовании.

Я часто слышу, как программисты на C говорят, что malloc() и free() - это дорогостоящие операции, но я никогда не слышал, чтобы программисты на C ++ говорили это о new и delete. Я также заметил, что в C ++ нет операции, которая соответствует C realloc().

Если бы я писал эквивалент класса C ++ vector, я бы хотел избежать копирования всего массива при изменении его размера, но с new и delete вам придется копировать. В C я бы просто realloc(). Стоит отметить, что realloc() может просто скопировать весь массив, но у меня сложилось впечатление, что он использовал тот же указатель и выделил для него меньше места, по крайней мере при уменьшении размера.

Итак, мой вопрос, как алгоритмы, используемые malloc() и free(), отличаются от алгоритмов, используемых new и delete. Более конкретно, почему способ C имеет клеймо быть более дорогим, и почему способ C ++ не позволяет изменять размеры без копирования?

Ответы [ 6 ]

5 голосов
/ 20 августа 2009

Под капотом нет никакой разницы - обычно операторы по умолчанию new и delete просто звонят на malloc и free.

Что касается "стигмы, которая стоит дороже", моя теория такова: в прошлом каждый цикл считался, и время, затраченное malloc, действительно было значительным во многих ситуациях. Но к моменту появления C ++ аппаратное обеспечение стало намного быстрее, а время, затраченное менеджером бесплатных магазинов, было пропорционально менее значительным. Акцент смещался с эффективного использования ресурсов машины на эффективное использование ресурсов программиста.

Почему C ++ не хватает realloc эквивалента, я не знаю.

2 голосов
/ 20 августа 2009

Часто new и delete используют malloc () и free () для выделения / освобождения памяти. В любом случае они должны использовать некоторые примитивы для выделения / освобождения памяти - с перегрузкой новых и удаления операторов, которые могут быть быстрее чем malloc () и free () (скажем, это могут быть функции, работающие в пул памяти для объектов фиксированного размера). Обычно, если вы действительно не сделали такую ​​перегрузку, вы не увидите никакой разницы в стоимости выделения памяти, выполняемой каждым из этих способов.

Перераспределение недопустимо просто потому, что не все типы данных позволяют перемещаться в памяти - им нужны вызываемые конструкторы копирования и деструкторы для правильного перемещения. Например, у вас могут быть некоторые структуры узлов графа, хранящиеся в массиве. Если вы перемещаете их вслепую, указатели между объектами станут недействительными.

1 голос
/ 20 августа 2009

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

new и delete вполне могут быть реализованы вашим компилятором очень похоже на malloc, но у них есть одно отличие (и именно поэтому они существуют) - они вызывают конструктор и деструктор для соответствующего элемента.

Когда я говорю «конструктор», я, конечно, имею в виду любую необходимую инициализацию (заполнение VTABLES, установка инициализаторов и т. Д.). Это может потенциально замедлить new и delete, но при параллельном сравнении (например, при выделении и освобождении int) принципиальной разницы нет.

1 голос
/ 20 августа 2009

Я не знаю о стигме C, но для изменения размера C ++. Вы можете использовать размещение новых, чтобы настроить поведение новых.

Но зачем это делать? Пусть производители компиляторов делают то, что умеют лучше всего!

1 голос
/ 20 августа 2009

«новые и удаление могут быть дорогостоящими операциями» - там, у вас есть сейчас слышал, как программист C ++ сказал это. А если серьезно, динамическое выделение памяти стоит одинаково на обоих языках.

0 голосов
/ 20 августа 2009

они в основном используют одни и те же методы для распределения - конечно, в большинстве реализаций стандартная среда выполнения C ++ new не будет намного быстрее, чем malloc. Одно из больших отличий заключается в том, что вы можете переписать распределитель в C ++, чтобы вы могли использовать распределители, оптимизированные под ожидаемое поведение памяти - вы можете делать это и в C, конечно, но это немного более громоздко в плане синтаксиса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...