Что происходит, когда вызывается malloc()/free()/create/delete?

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

В Windows или Linux, когда программа выделяет память, происходит целая куча вещей, таких как функции, связанные с виртуализацией и безопасностью, которые не имеют отношения к arduino, и то, что меня интересует, управление памятью:

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

Существует ли пользовательская реализация malloc для каждого устройства, или она поставляется с набором инструментов arduino (и означает ли это, что Arduino имеет реализацию, отличную от Teensy, или avr от sam?), или существует какая-то волшебная реализация по умолчанию, предоставляемая компилятором? Какие накладные расходы на память возникают при каждом выделении? Насколько легко переопределить эту функциональность и реализовать свою собственную (из болезненного любопытства или склонности к мазохистским начинаниям)?

, 👍2

Обсуждение

Обзор функции "malloc ()" в AVR см. [эта страница документации avr-libc]. (https://www.nongnu.org/avr-libc/user-manual/malloc.html)., @Edgar Bonet

Что касается "каждого устройства" против "цепочки инструментов Arduino" и "malloc":, в основном ни то, ни другое. Это часть реализации libc, которая обычно охватывает множество устройств. Настройка libc malloc алгоритмическим способом обычно означает исправление сборки libc самостоятельно. Есть несколько специфичных для Arduino заглушек, например, для "нового" / "удаления" и перемещения разрыва стека/кучи, но большая часть того, о чем вы спрашиваете (а это много), на самом деле не имеет большого отношения к Arduino., @timemage

Четыре или около того реализации без AVR `malloc (), которые я рассматривал, включая Due и ESP8266, используют ту же базовую схему, описанную в ссылке EdgarBonet, и настраиваются примерно одинаково., @timemage

Афаик "избегайте динамического распределения"-это MCU, я спросил об этом профессионального (не встроенного) разработчика C++, и он выглядел озадаченным, но согласился, что этого следует избегать, если программист не знает, что они делают. Без операционной системы микроконтроллер не может очистить мусор, поэтому ошибки имеют гораздо большее значение, чем на ПК, но динамическое распределение, безусловно, может быть выполнено и выполнено надежно на микроконтроллере, если системные параметры понятны и соблюдаются., @dandavis

Мне жаль @dandavis, но я вижу "MCU", и все, о чем я могу думать, это определенная франшиза для комиксов., @Dan Forever

Мы склонны использовать MCU для микроконтроллера, некоторые люди используют просто микро для краткости. Сначала это немного сбивало с толку., @SimonVu14


1 ответ


2

Существуют некоторые аппаратно-специфические абстракции (они в основном определяют максимальный объем доступной памяти), но в остальном это функции, реализуемые средой выполнения C/C++ (на ардуино реализация называется "NewLib") и обычно "просто работают". Возможно, вам захочется взглянуть на этот вопрос, где довольно много информации о реализации абстракций аппаратного обеспечения SAM (потому что она нарушена).

И да, конечно, использование malloc/free имеет некоторые значительные накладные расходы, что является одной из причин, по которой это не рекомендуемый способ распределения памяти на микроконтроллерах. Но логика, лежащая в его основе, в основном одинакова, независимо от того, есть ли 2 кб памяти или 2 ГБ. И модель памяти современных микроконтроллеров (по крайней мере, 32-разрядных) очень похожа на ту, которую можно увидеть в 32-разрядных приложениях для Windows или Linux.

,