• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

где делать объявление локальных переменных

enjoynering

Well-known member
Мучает впорс по оптимизации памяти. Как мы все знаем в МК есть стек (stack) и куча(heap). Стек для глобальных переменных и сним ПОКА впросов нет. А вот куча которая используется для локальных переменных, находящихся внутри различных функций, не дает мне спать.

Вот пример кода для затравки

Код:
void webTest()
{
  bool    changed = false;
  String  load    = " ";

  Serial.println("\r\nrequest TEST");
  float x = 345.345/345.567;

  load = WebServer.arg("module");
  if (load.length() > 0)
 {
   changed = true
 }
Здесь мы объявили переменные changed и load в начале функции. Вопрос первый: changed имеет размерность одни байт, но ESP8266 у нас 32 битный. Зачит ли это что для changed в куче выделится 32 бита? Впрос второй: как мы знаем переменные типа String - это безразмерный Array типа Char. Я инициализировал load c пробелом. Значит в куче под него будет 1 байт. Потом мы выделил в куче место под float x. По идее оно должно встать в куче сразу за пробелом? Потом я начинаю принимать в load данные от сервера которые уже например 20 байт. Как поведет себя куча в этом случае если у меня до этого под load выделилось всего 1 байт?

Не лучше бы сделать так?

Код:
void webTest()
{
  bool    changed = false;

  Serial.println("\r\nrequest TEST");
  float x = 345.345/345.567;

  String load = WebServer.arg("module");
  if (load.length() > 0)
  {
   changed = true
  }
Заранее спсибо.
 

Юрий Ботов

Moderator
Команда форума
1. В микроконтроллере нет ни стэка ни кучи. У него есть RAM и как ее распредилить - ваша забота.
2. Стэк и куча это изначально части модели памяти языка С и его потомков. Разница в том что распределение и освобождение памяти в стэке автоматическое, но при помощи его в С сложно(хоть и можно) разместить массивы, строки или другие сложные объекты. Кроме того выделение памяти в стэке не контролируется, и можно не глядя затереть что нибудь нужное или вызвать исключение защиты памяти.
Распределение/освобождение из кучи (heap) происходит с использованием alloc/free и можно проконтролировать дали тебе память или нет, что безопаснее для больших объектов.
3. Все локальные переменные функций С-подобные языки хранят в СТЭКЕ. Если объект большой - то в стэке хранится ссылка на объект который сам засовывается в кучу.
У вас в webTest:
changed (имеет размерность 1 БИТ) - кладется в стэк занимая 32 бита. (если битовых переменных несколько хороший компилятор положит их в одно 32 разрядное слово)
load (ссылка на объект String) кладется в стэк, сам объект String " " кладется в кучу, кроме пробела и 0 символа туда кладутся еще несколько параметров объекта типа "String". Не путайте объект String и массив символов char* ЭТО АБСОЛЮТНО РАЗНЫЕ ВЕЩИ.
x - кладется в стэк

Вообще в C при вызове функции кладутся:
- передаваемые параметры в порядке поступления
- адрес возврата
- локальные переменные функции
при этом указатель стэка внутри функции указывает на адрес возврата.

Теперь понятно почему я не отвечаю конкретно на ваш вопрос?
 
Последнее редактирование:
Сверху Снизу