Ответ 1
Преимущество заключается в том, что realloc сохранит содержимое памяти. С бесплатным + malloc вам нужно reset данные в массиве.
Зачем использовать функцию realloc() для изменения размера динамически распределенного массива вместо использования функции free(), прежде чем снова вызвать функцию malloc() (т.е. плюсы и минусы, преимущества и недостатки и т.д.)? Это для программирования на C, но я не могу найти для него правильный тег. Спасибо заранее.
Преимущество заключается в том, что realloc сохранит содержимое памяти. С бесплатным + malloc вам нужно reset данные в массиве.
Я знаю, что этот вопрос очень старый (на него был дан ответ в 2009 году), но я надеюсь, что мой ответ поможет тем, кто ищет и сталкивается с этим вопросом (например, я).
Хотя этот тест не является окончательным, так как управление памятью варьируется в разных системах, в настоящее время все имеет тенденцию быть довольно стандартизированным, поэтому эти результаты должны быть безопасными для использования в качестве контрольной точки (если вы знаете о реальной жизни, это не, пожалуйста скажи мне). Я использую Windows 7 на 2.10GHz QuadCore Intel Core i3 2310M с 4 ГБ оперативной памяти. Не лучшее оборудование, но лучшее, что у меня есть сейчас.
Что делает этот тест, он начинается с определенного объема памяти (INITIAL_MEMORY) и повторно перераспределяется на небольшие суммы (BYTE_STEP), пока он полностью не выделяет/освобождает ALLOCATE_MEMORY. Для этого он пытается использовать 6 подходов:
Итак, первый тест: начните с 2 МБ и выделите ± 1 МБ с шагом 1 КБ:
Increasing Lossful Malloc took 3 ms
Decreasing Lossful Malloc took 5 ms
Increasing Malloc took 1 265 ms
Decreasing Malloc took 744 ms
Increasing Realloc took 316 ms
Decreasing Realloc took 0 ms
Как мы видим, копирование вручную с помощью memcpy всегда медленнее, чем realloc, поскольку в этом случае malloc гарантированно выделяет новую память, и вы вынуждены копировать данные в каждом распределении, что показывает нам, что realloc действительно повторно использует тот же адрес и увеличение размера блока в некоторых случаях. Поэтому, если вы хотите сохранить свои данные, realloc - это, вероятно, то, что вы хотите использовать. Чтобы упростить ситуацию, я не буду проверять этот безлимитный подход malloc.
Переходим к следующему тесту: начальная память 32 МБ, распределение 16 МБ с шагом 16 КБ:
Increasing Lossful Malloc took 4 ms
Decreasing Lossful Malloc took 4 ms
Increasing Realloc took 21 453 ms
Decreasing Realloc took 0 ms
Теперь мы видим, что увеличение realloc занимает много времени по сравнению с другими тестами. Уменьшение realloc даже не достигло 1 мс. Это показывает, что если вы не хотите хранить свою память, вы должны использовать метод free- > malloc или это сделать? Посмотрите на эти результаты:
Increasing Lossful Malloc took 777 ms
Decreasing Lossful Malloc took 729 ms
Decreasing Realloc took 19 ms
(Эти результаты были слишком близки, поэтому я провел несколько тестов и усреднил их.)
Определенное уменьшение размера памяти более эффективно при использовании realloc(). Вероятно, потому, что realloc не нуждается в поиске нового блока памяти, он просто использует предыдущий и сжимает его. Это большая разница в производительности, если вы сильно используете распределение.
Кроме того, мы видим, что увеличение malloc немного медленнее, чем уменьшение, даже если оба они в основном одинаковы: найдите блок памяти и выделите его. Это различие, вероятно, связано с тем, что при поиске больших блоков malloc нужно искать больше в среднем, чем при поиске меньших блоков. Например, если есть блок размером 30 МБ, он будет использовать malloc, выделяющий 16 МБ, но malloc, выделяющий 32 МБ, должен будет пропустить его и продолжить поиск и использование времени выполнения. Вероятно, это связано с тем, что результаты менялись так сильно в моих тестах.
В заключение /TL;DR:
Здесь мой базовый источник: test.cpp
Теперь, пожалуйста, если я сделал что-то неправильно или у вас есть какие-либо комментарии, не стесняйтесь сказать/исправить меня.
Ну, realloc может изменить размер блока на месте или выделить новый и скопировать столько, сколько будет соответствовать. Напротив, malloc и свободные вместе могут выделять только новый, и вам нужно сделать свое собственное копирование.
Чтобы быть откровенным, realloc не получает столько пользы в наши дни, потому что это плохо работает с С++. В результате у менеджеров памяти не было оптимизма для оптимизации.
У меня была программа, которая выполняла кучу вызовов free() и malloc() для создания динамического массива, и я думал, что буду оптимизировать, повторно используя существующий массив, когда это возможно. Тесты показали, что realloc() в среднем медленнее, чем просто вызов free() и malloc(). Я предполагаю, что это имеет смысл, так как иногда оно будет расти и, возможно, потребуется скопировать.
"вместо использования функции free() перед вызовом функции malloc() снова"
Если вы освободите существующий массив, вы потеряли все его содержимое, чтобы вы не могли "вырастить" массив в обычном смысле.