Нужно ли удалять переменные перед сном?

В этом руководстве показано, как перевести 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();

     // так далее...
     // ....
}

, 👍0

Обсуждение

Нет, не знаешь. Вам просто нужно освободить ее, прежде чем пытаться использовать эту память для чего-либо еще. На самом деле на микроконтроллере я бы создал объект в меньшей области и попытался сделать все, что в моих силах, чтобы избежать использования новой или любой другой формы динамического распределения. Обычно в такой среде есть лучшие способы обойти это. Сильно отличается от написания кода для запуска на ПК., @Delta_G


1 ответ


Лучший ответ:

3

Возможно, вы уже знаете, что объекты, созданные с помощью new, хранятся в куча, а глобальные переменные хранятся в разделах .data и .bss, а локальные в стеке¹. Однако это различие существует только в программного обеспечения. На аппаратном уровне .data, .bss, куча и стек просто произвольные части оперативной памяти.

Подумайте, что произойдет, если ОЗУ будет стерто или каким-либо образом повреждено, когда микроконтроллер спит. Это не только повлияет на объекты в куче, но и каждую переменную в программе. И даже обратный адрес из вызова gotToSleepAndWakeUpIn4Seconds() будет быть потеряны, поэтому ЦП не знал бы, где возобновить выполнение, когда он просыпается. Единственная разумная вещь, которую можно сделать после пробуждения, это перезапустите программу с нуля. И это на самом деле то, что происходит, когда вы сбрасываете микроконтроллер².

Но сон — это не сброс. Содержимое ОЗУ сохраняется при спать. Это означает, что сохраняется все состояние программы: локальные, глобальные и объекты в куче. Не нужно удалять и создавать заново вещи.

Кроме того, если вы можете выделить память статически, это обычно лучше, чем динамическое распределение, и вы избегаете риска кучи фрагментация:

Foo someObject(arg1, arg2, ..);  // статический глобальный экземпляр

void loop()
{
    // Тогда какой-нибудь код,

    if (something)
        someObject.executeFunction1();
}

Примечания:
¹ В качестве оптимизации локальные переменные текущего фрейма стека могут находиться в ЦП. регистрирует, но вывод это не меняет.
² На AVR теплый сброс не приводит к потере ОЗУ, но затем повторно инициализируется средой выполнения C. Холодный сброс (включение-выключение) теряет ОЗУ.

,