Динамическое выделение памяти malloc, realloc ?

k4889
Offline
Зарегистрирован: 10.02.2017
Из-за недостатка знаний не могу решить вопрос с динамическим массивом:
Есть структура mainInfo, признак connection у блоков меняется постоянно (в зависимости от уловий, где-то по ходу программы).
На основании этого признака нужно собрать динамический массив bloksActiveArray, в котором может быть от 0 до 6 номеров.
Вроде написал, используя мануалы, но оно все равно не работает. Если все connection = false, то массив все равно не пустой.
byte *bloksActiveArray; 

struct bloksInfo {
 char Name[15];			//Имя
 boolean connection;	//Подключен (Да, Нет)
};

struct bloksInfo mainInfo[] = {
                                {"Block 1", false},
                                {"Block 2", false},
                                {"Block 3", false},
                                {"Block 4", true},
                                {"Block 5", true},
                                {"Block 6", true}
};

void setup()
{  
}

void loop()
{  
  // Посчитаем количество подключенных блоков и   
  // Если блоки есть, то надо записать их номера в динамический массив
  byte pos = 0;
  free(bloksActiveArray); // Очистим динамический массив
  bloksActiveArray = (byte *) malloc(0); // зададим нулевой размер
  for (int i = 0; i < sizeof(mainInfo)/sizeof(mainInfo[0]); i++)
  {
      if (mainInfo[i].connection)
      {
        (byte *)realloc(bloksActiveArray, sizeof(bloksActiveArray) + sizeof(byte)); // Увеличим размер массива на 1 byte
		bloksActiveArray[pos] = i; // Заполним номер
        pos++;
      }
  }

  printInfo();
}

void printInfo()
{
  if (sizeof(bloksActiveArray) > 0){/*Что-то делаем*/} else {/*Что-то делаем*/}
}


 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

k4889 пишет:
Из-за недостатка знаний не могу решить вопрос с динамическим массивом
Из-за недостатка Ваших знаний объянить Вам будет сложно.

k4889
Offline
Зарегистрирован: 10.02.2017

qwone пишет:

Из-за недостатка Ваших знаний объянить Вам будет сложно.

Можно пример привести, я попробую разобраться.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

https://goo.gl/yQaGj5  Но там много букв.

k4889
Offline
Зарегистрирован: 10.02.2017

Так будет правильно ?

void loop()
{   
  byte *bloksActiveArray = NULL;
  byte bloksArrayPosition = 0;
  for (int i = 0; i < sizeof(mainInfo)/sizeof(mainInfo[0]); i++) {if (mainInfo[i].connection) {bloksArrayPosition++;}}  
  
  if (bloksArrayPosition > 0)
  {
    bloksActiveArray = (byte*) malloc(sizeof(byte) * bloksArrayPosition);
    byte bloksArrayPosition = 0;
    for (int i = 0; i < sizeof(mainInfo)/sizeof(mainInfo[0]); i++)
    {
      if (mainInfo[i].connection)
      {
        bloksActiveArray[bloksArrayPosition] = i;
        bloksArrayPosition++;
      }
    }
  }

  printInfo();
  
  free(bloksActiveArray);
}

void printInfo()
{
  if (bloksArrayPosition != NULL) {/*Что-то делаем*/} else {/*Что-то делаем*/}
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

k4889, главная ваша ошибка в том что вы не думаете как Си-шник. Вот и пишите как Бейсик-шник. Вот и вызит туфта.

k4889
Offline
Зарегистрирован: 10.02.2017

qwone пишет:

k4889, главная ваша ошибка в том что вы не думаете как Си-шник. Вот и пишите как Бейсик-шник. Вот и вызит туфта.

Возможно потому, что я с C++ не работал раньше ? Помощь, вместо тонны текста была бы куда более ценна.

sadman41
Offline
Зарегистрирован: 19.10.2016

А вам вообще зачем такой массив-то нужен? В МК с управлением памятью не так всё шоколадно, как в больших системах, поэтому тащить в Ардуину приемчики из книжек по C++ не всегда полезно.

k4889
Offline
Зарегистрирован: 10.02.2017

sadman41 пишет:

А вам вообще зачем такой массив-то нужен? В МК с управлением памятью не так всё шоколадно, как в больших системах, поэтому тащить в Ардуину приемчики из книжек по C++ не всегда полезно.

Пишу код для управления автополивом. Управляющий блок связан с остальными по радио и в структуре как раз хранятся данные о подключении. С динамическим массивом потом работать намного проще, чем хариться по структуре, запоминать позиции и т.д.

Прошлись, выдернули нужные данные и с ними уже работаем.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Посмотрите, может поможет. Там есть и программа для исследования состояния памяти, заодно

sadman41
Offline
Зарегистрирован: 19.10.2016

Количество "абонентов" конечное? Прикиньте по памяти - сильно ли ударит создание массива максимального объема? Если даже байт 100-200 - лично я бы даже не морочался со всей этой динамикой. Дороже выйдет алгоритм написать так, чтобы стек не пропороть.

k4889
Offline
Зарегистрирован: 10.02.2017

sadman41 пишет:

Количество "абонентов" конечное? Прикиньте по памяти - сильно ли ударит создание массива максимального объема? Если даже байт 100-200 - лично я бы даже не морочался со всей этой динамикой. Дороже выйдет алгоритм написать так, чтобы стек не пропороть.

Количество абонентов конечное, насколько мне известно nrf24l01 не умеет работать более чем с 6 каналами одновременно. Просто на основе количества выводятся данные в меню на дипслей и при работе со структурой ее нужно постоянно перебирать, хранить данные о позиции, проверять есть ли дальше активные блоки и т.д. Код сильно вырастает и усложняется. А с динамическим массивом проще - взяли первый элемент, что-то сделали, нужно пойти дальше, инкрементировали позицию в массиве на 1 и все. Это как пример.

sadman41
Offline
Зарегистрирован: 19.10.2016

Я не о том. Создаете постоянный массив структур на 6 позиций, сканируете эфир, заполняете, индекс последнего элемента суете в глобальную переменную n, например. Далее просто бегаете от нуля до n, если нужно перебрать все активные датчики. По-моему в данных условиях это менее монстроузно, чем лепить malloc-и.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

k4889 пишет:
массив все равно не пустой.

С чего Вы сделали такой вывод? Их проверки в 43-ей строке? Так она не имеет никакого отношения к пустоте или не пустоте массива. sizeof(bloksActiveArray) всегда равно 2, чтобы Вы там с массивом не делали. Напечатайте её в Serial и убедитесь.

sadman41
Offline
Зарегистрирован: 19.10.2016

Да, вот, кстати, если по массиву, то можно сделать так: строки сложить в PROGMEM, в структуре предусмотреть на них указатель. При сканировании связывать элемент массива с константой из PROGMEM, опираясь на ID, полученный от удаленного модуля. Инициализация позамороченней, зато весь массив, вроде как, в 18 байт ОЗУ уложится. И, опять же, нет страданий, связанных с диспетчеризацией памяти.

k4889
Offline
Зарегистрирован: 10.02.2017

sadman41 пишет:

Я не о том. Создаете постоянный массив структур на 6 позиций, сканируете эфир, заполняете, индекс последнего элемента суете в глобальную переменную n, например. Далее просто бегаете от нуля до n, если нужно перебрать все активные датчики. По-моему в данных условиях это менее монстроузно, чем лепить malloc-и.

Да, возможно вы правы, но также нужно хранить данные и об отключенных устрайствах, т.е. структура в примере упрощенная. А это накладывает сортировку структуры, чтобы скажем между 1 и 3-м элементом не попался 2-й, который отключен. Как пример.

ЕвгенийП пишет:

Так она не имеет никакого отношения к пустоте или не пустоте массива. sizeof(bloksActiveArray) всегда равно 2, чтобы Вы там с массивом не делали.

Печал, да он всегда выводит 2. Догадался почему, спасибо.

Только не понял, как в таком случае получить размер массива !?

 

 

 

k4889
Offline
Зарегистрирован: 10.02.2017

sadman41 пишет:

Да, вот, кстати, если по массиву, то можно сделать так: строки сложить в PROGMEM, в структуре предусмотреть на них указатель. При сканировании связывать элемент массива с константой из PROGMEM, опираясь на ID, полученный от удаленного модуля. Инициализация позамороченней, зато весь массив, вроде как, в 18 байт ОЗУ уложится. И, опять же, нет страданий, связанных с диспетчеризацией памяти.

А это кстати очень здравая мысль. Как я сам не догадался )))

k4889
Offline
Зарегистрирован: 10.02.2017

По совету sadman41 реализовал со сторокой. Заняло пару минут, за что ему большое спасибо. Да и всем остальным тоже.

void loop()
{    
  // Посчитаем количество подключенных блоков    
  String bloksActiveStr = "";
  for (int i = 0; i < sizeof(mainInfo)/sizeof(mainInfo[0]); i++) 
  {
    if (mainInfo[i].connection) {bloksActiveStr += String(i);}
  }
  
  // Посмотрим что получилось
  for (int i = 0; i < bloksActiveStr.length(); i++)
  {
    Serial.println(bloksActiveStr[i]);  
  }
  Serial.println();
}

// ---------------------------------------------------------------- END ----------------------------------------------------------------



void printInfo()
{
  if (bloksActiveStr != "") 
  {
	/*Что-то делаем*/
  } else {/*Что-то делаем*/}
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Третий закон Чизхолма подтвержден.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

k4889 пишет:
Возможно потому, что я с C++ не работал раньше ? Помощь, вместо тонны текста была бы куда более ценна.
Не за что цепляться. Вы везде ... "гладкий". Так что учитесь или заказывайте. http://cpp.com.ru/kr_cbook/ch6kr.html

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

k4889 пишет:

Только не понял, как в таком случае получить размер массива !?

Его не надо получать, его надо - знать.