Динамическое выделение памяти malloc, realloc ?
- Войдите на сайт для отправки комментариев
Ср, 02/05/2018 - 20:11
Из-за недостатка знаний не могу решить вопрос с динамическим массивом:
Есть структура 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 {/*Что-то делаем*/}
}
Из-за недостатка Ваших знаний объянить Вам будет сложно.
Можно пример привести, я попробую разобраться.
https://goo.gl/yQaGj5 Но там много букв.
Так будет правильно ?
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 {/*Что-то делаем*/} }k4889, главная ваша ошибка в том что вы не думаете как Си-шник. Вот и пишите как Бейсик-шник. Вот и вызит туфта.
k4889, главная ваша ошибка в том что вы не думаете как Си-шник. Вот и пишите как Бейсик-шник. Вот и вызит туфта.
Возможно потому, что я с C++ не работал раньше ? Помощь, вместо тонны текста была бы куда более ценна.
А вам вообще зачем такой массив-то нужен? В МК с управлением памятью не так всё шоколадно, как в больших системах, поэтому тащить в Ардуину приемчики из книжек по C++ не всегда полезно.
А вам вообще зачем такой массив-то нужен? В МК с управлением памятью не так всё шоколадно, как в больших системах, поэтому тащить в Ардуину приемчики из книжек по C++ не всегда полезно.
Пишу код для управления автополивом. Управляющий блок связан с остальными по радио и в структуре как раз хранятся данные о подключении. С динамическим массивом потом работать намного проще, чем хариться по структуре, запоминать позиции и т.д.
Прошлись, выдернули нужные данные и с ними уже работаем.
Посмотрите, может поможет. Там есть и программа для исследования состояния памяти, заодно
Количество "абонентов" конечное? Прикиньте по памяти - сильно ли ударит создание массива максимального объема? Если даже байт 100-200 - лично я бы даже не морочался со всей этой динамикой. Дороже выйдет алгоритм написать так, чтобы стек не пропороть.
Количество "абонентов" конечное? Прикиньте по памяти - сильно ли ударит создание массива максимального объема? Если даже байт 100-200 - лично я бы даже не морочался со всей этой динамикой. Дороже выйдет алгоритм написать так, чтобы стек не пропороть.
Количество абонентов конечное, насколько мне известно nrf24l01 не умеет работать более чем с 6 каналами одновременно. Просто на основе количества выводятся данные в меню на дипслей и при работе со структурой ее нужно постоянно перебирать, хранить данные о позиции, проверять есть ли дальше активные блоки и т.д. Код сильно вырастает и усложняется. А с динамическим массивом проще - взяли первый элемент, что-то сделали, нужно пойти дальше, инкрементировали позицию в массиве на 1 и все. Это как пример.
Я не о том. Создаете постоянный массив структур на 6 позиций, сканируете эфир, заполняете, индекс последнего элемента суете в глобальную переменную n, например. Далее просто бегаете от нуля до n, если нужно перебрать все активные датчики. По-моему в данных условиях это менее монстроузно, чем лепить malloc-и.
С чего Вы сделали такой вывод? Их проверки в 43-ей строке? Так она не имеет никакого отношения к пустоте или не пустоте массива.
sizeof(bloksActiveArray)всегда равно 2, чтобы Вы там с массивом не делали. Напечатайте её в Serial и убедитесь.Да, вот, кстати, если по массиву, то можно сделать так: строки сложить в PROGMEM, в структуре предусмотреть на них указатель. При сканировании связывать элемент массива с константой из PROGMEM, опираясь на ID, полученный от удаленного модуля. Инициализация позамороченней, зато весь массив, вроде как, в 18 байт ОЗУ уложится. И, опять же, нет страданий, связанных с диспетчеризацией памяти.
Я не о том. Создаете постоянный массив структур на 6 позиций, сканируете эфир, заполняете, индекс последнего элемента суете в глобальную переменную n, например. Далее просто бегаете от нуля до n, если нужно перебрать все активные датчики. По-моему в данных условиях это менее монстроузно, чем лепить malloc-и.
Да, возможно вы правы, но также нужно хранить данные и об отключенных устрайствах, т.е. структура в примере упрощенная. А это накладывает сортировку структуры, чтобы скажем между 1 и 3-м элементом не попался 2-й, который отключен. Как пример.
Так она не имеет никакого отношения к пустоте или не пустоте массива.
sizeof(bloksActiveArray)всегда равно 2, чтобы Вы там с массивом не делали.Печал, да он всегда выводит 2. Догадался почему, спасибо.
Только не понял, как в таком случае получить размер массива !?
Да, вот, кстати, если по массиву, то можно сделать так: строки сложить в PROGMEM, в структуре предусмотреть на них указатель. При сканировании связывать элемент массива с константой из PROGMEM, опираясь на ID, полученный от удаленного модуля. Инициализация позамороченней, зато весь массив, вроде как, в 18 байт ОЗУ уложится. И, опять же, нет страданий, связанных с диспетчеризацией памяти.
А это кстати очень здравая мысль. Как я сам не догадался )))
По совету 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 {/*Что-то делаем*/} }Третий закон Чизхолма подтвержден.
Только не понял, как в таком случае получить размер массива !?
Его не надо получать, его надо - знать.