Нужно ли удалять переменные перед сном?
В этом руководстве показано, как перевести Arduino в спящий режим и использовать сторожевой таймер для пробуждения через определенные промежутки времени:
https://youtu.be/urLSDi7SD8M
Я изучаю C++ и, по мере того, как становлюсь лучше, создаю экземпляры объектов с помощью ключевого слова new
. Я узнал, что если вы создаете что-то с ключевым словом new
, вы несете ответственность за удаление этого из памяти, когда оно вам больше не нужно. Но я не знаю, применимо ли это, когда вы переводите Arduino в спящий режим.
В любом случае, мой вопрос в комментариях к коду:
Foo * someObject;
void setup()
{
someObject = new Foo(arg1, arg2, ..); // создаем экземпляр someObject
// инициировать контакты и т. д..
}
void loop()
{
if(button1Pressed())
{
// **** ОБЯЗАТЕЛЬНО УДАЛИТЬ ОБЪЕКТЫ ПЕРЕД СОНОМ? Нужна ли мне эта линия? ****
delete someObject;
gotToSleepAndWakeUpIn4Seconds() ; // переводит arduino в спящий режим и снова просыпается через 4 секунды
int x = 0; // эта строка никогда не выполняется arduino находится в спящем режиме и снова проснется через 4 секунды
}
// больше кода
if(something)
someObject->executeFunction1();
// так далее...
// ....
}
@Tono Nam, 👍0
Обсуждение1 ответ
Лучший ответ:
Возможно, вы уже знаете, что объекты, созданные с помощью new
, хранятся в
куча, а глобальные переменные хранятся в разделах .data и .bss, а
локальные в стеке¹. Однако это различие существует только в
программного обеспечения. На аппаратном уровне .data, .bss, куча и стек просто
произвольные части оперативной памяти.
Подумайте, что произойдет, если ОЗУ будет стерто или каким-либо образом повреждено,
когда микроконтроллер спит. Это не только повлияет на
объекты в куче, но и каждую переменную в программе. И даже
обратный адрес из вызова gotToSleepAndWakeUpIn4Seconds()
будет
быть потеряны, поэтому ЦП не знал бы, где возобновить выполнение, когда он
просыпается. Единственная разумная вещь, которую можно сделать после пробуждения, это
перезапустите программу с нуля. И это на самом деле то, что происходит, когда
вы сбрасываете микроконтроллер².
Но сон — это не сброс. Содержимое ОЗУ сохраняется при спать. Это означает, что сохраняется все состояние программы: локальные, глобальные и объекты в куче. Не нужно удалять и создавать заново вещи.
Кроме того, если вы можете выделить память статически, это обычно лучше, чем динамическое распределение, и вы избегаете риска кучи фрагментация:
Foo someObject(arg1, arg2, ..); // статический глобальный экземпляр
void loop()
{
// Тогда какой-нибудь код,
if (something)
someObject.executeFunction1();
}
Примечания:
¹ В качестве оптимизации локальные переменные текущего фрейма стека могут находиться в ЦП.
регистрирует, но вывод это не меняет.
² На AVR теплый сброс не приводит к потере ОЗУ, но затем
повторно инициализируется средой выполнения C. Холодный сброс (включение-выключение) теряет
ОЗУ.
- Почему считается плохой практикой использовать ключевое слово "new" в Arduino?
- Использование памяти: #define против static const для uint8_t
- Есть ли ограничения на размер массива в Arduino Mega 2560?
- Считывание байтов из массива PROGMEM
- Понимание глобальных переменных на Arduino
- Как уменьшить использование глобальных переменных? Attiny85
- deserializeJson() не удалось: NoMemory при отправке последовательного json с использованием ArduinoJson
- Проблема с переменной char* malloc/free. Пустое содержимое в переменной получателя после использования free
Нет, не знаешь. Вам просто нужно освободить ее, прежде чем пытаться использовать эту память для чего-либо еще. На самом деле на микроконтроллере я бы создал объект в меньшей области и попытался сделать все, что в моих силах, чтобы избежать использования новой или любой другой формы динамического распределения. Обычно в такой среде есть лучшие способы обойти это. Сильно отличается от написания кода для запуска на ПК., @Delta_G