Перейти к содержанию
    

Безразмерные массивы, как с ними правильно работать?

Как это иногда бывает, пишешь-пишешь программу, и вдруг то, что раньше работало, перестает работать. Хотя не трогал этого уже неделю, а напрограммировал с тех пор много.

Объявил я вот такую штуку

uint8_t str[] = "Some Text\r\n";

После чего в определенном месте программа просто стала виснуть наглухо. Долго ковырял и выяснилось, что если обозначить размер str, то глюк исчезает.

А мне вот понадобилось создать массив из строк. Строки имеют конечную длину, а количество их заранее неизвестно. Как создать массив из строк с заранее неизвестным числом элементов и при этом не наломать дров с использованием памяти? Пишу под STM32 в Keil, если что.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, -=Женек=- сказал:

После чего в определенном месте программа просто стала виснуть наглухо...

Какое, однако, точное описание...
Процессор Cortex-Mx виснет только в одном случае - в состоянии блокировки.
В остальных 99.999% он все-таки выполняет какой-никакой, но вполне определенный код, или спит:smile:

14 минут назад, -=Женек=- сказал:

Долго ковырял и выяснилось, что если обозначить размер str, то глюк исчезает.

Значит программа так написана, либо Вы где-то разошлись в понятиях с языком Си...

14 минут назад, -=Женек=- сказал:

А мне вот понадобилось создать массив из строк. Строки имеют конечную длину, а количество их заранее неизвестно. Как создать массив из строк с заранее неизвестным числом элементов и при этом не наломать дров с использованием памяти?

#define STR_MAX_LEN 10

const char str[][STR_MAX_LEN] = {"string 1",
                                 "string 2",
                                  ...
                                 "string N"};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, Arlleex said:

#define STR_MAX_LEN 10 const char str[][STR_MAX_LEN] = {"string 1", "string 2", ... "string N"};

Идея хорошая, но у меня не константа, а массив переменных.

То есть остается 

char str[][STR_MAX_LEN] 

C длиной имен проблем нет, с количеством - могут возникнуть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 часов назад, -=Женек=- сказал:

Идея хорошая, но у меня не константа, а массив переменных.
C длиной имен проблем нет, с количеством - могут возникнуть.

Простите, что?:wacko2: Что Вы хотите?
Вы написали, что хотите объявить массив строк.
И писать циферку в размерности массива не хотите.
Я и написал, как объявить массив так, чтобы не писать одну размерность.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Arlleex said:

Вы написали, что хотите объявить массив строк.

хочу объявить массив строковых переменных, которые буду заполнять программно, в процессе работы.

 

13 minutes ago, Arlleex said:

Я и написал, как объявить массив так, чтобы не писать одну размерность.

Как не писать - я знаю. А вот как сделать, чтобы при этом не было глюков...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, -=Женек=- сказал:

хочу объявить массив строковых переменных, которые буду заполнять программно, в процессе работы.

А. Т.е. и инициализирующих значений в тех строках нет? Тогда никак. Значит придется писать обе размерности.

6 минут назад, -=Женек=- сказал:

А вот как сделать, чтобы при этом не было глюков...

Каких глюков?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Arlleex said:

Тогда никак. Значит придется писать обе размерности.

К примеру, прочел я список файлов и хочу его куда-нибудь передать.

Как бы вы объявляли массив под это дело? В FAT32 к примеру в папке может поместиться 65535 файлов с длиной имени 256 байт. Не хило так, правда?

Конечно, можно их никуда не запаковывать, а сразу выводить, но с этим есть определенные неудобства.....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как передать содержимое флешки на 64ГБ при объеме ОЗУ в МК, к которому она подключена, в 8кБ?
Вот и с именами так же. Вычитали кусочек - передали. Вычитали - передали. И так пока список не кончится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 часов назад, -=Женек=- сказал:

Как создать массив из строк с заранее неизвестным числом элементов и при этом не наломать дров с использованием памяти?

Это невозможно. Памяти в любом компьютере или микроконтроллере всегда конечное число. Вы же предлагаете создать массив с неизвестным объёмом. А вдруг числа молекул всей Вселенной не хватит, чтобы сохранить ваш объём данных?

7 часов назад, -=Женек=- сказал:

но с этим есть определенные неудобства.....

Вам необходимо пересмотреть алгоритм вашего ПО.

7 часов назад, -=Женек=- сказал:

В FAT32 к примеру в папке может поместиться 65535 файлов с длиной имени 256 байт.

В стартовом сообщении темы следует сразу оговорить все аспекты вашей задачи, ведь телепатов на этом форуме не очень много, да и они работают за плату))) Рассмотрите, как вариант, использование динамической памяти: malloc/free под Си или new/delete Си++.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 часов назад, -=Женек=- сказал:

К примеру, прочел я список файлов и хочу его куда-нибудь передать.

1. В программе объявляете указатель на массив

2. Если вы прочли список файлов в fat32, то уже знаете длину каждого файла и суммарный объем данных

3. Выделяете в памяти область под известный  объем (malloc())

4. Загружаете в эту область свои данные из файлов (например)

5. Передаете эти данные куда нужно

6. Освобождаете зарезервированную в п. 3 область (free())

В любом случае неизвестных размеров не бывает, вы их должны узнать перед требуемыми действиями.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, V_G said:

1. В программе объявляете указатель на массив

2. Если вы прочли список файлов в fat32, то уже знаете длину каждого файла и суммарный объем данных

3. Выделяете в памяти область под известный  объем (malloc())

4. Загружаете в эту область свои данные из файлов (например)

5. Передаете эти данные куда нужно

6. Освобождаете зарезервированную в п. 3 область (free())

В любом случае неизвестных размеров не бывает, вы их должны узнать перед требуемыми действиями.

Спасибо! Наилучший совет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, rkit said:

Следующая тема - почему у меня железка произвольно крашится.

Это насмешка над моим дилетантсвом (коего я не стесняюсь, ибо любитель), или намек на то, что предыдущий совет плох?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Учитывая то, в каком разделе был создан топик, не думаю, что это была насмешка.
Ибо совет в его чистом виде по malloc()/free() - действительно прямой путь к краху.
Однако, если самому реализовать механизмы выделения/освобождения памяти, то вполне себе решение.
Правда, для более-менее контролируемой работы этих функций придется ввести ряд естественных ограничений.
В итоге все сведется к первому варианту - проще будет выделить массив под известное количество строк и работать с ним.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

33 minutes ago, -=Женек=- said:

Это насмешка над моим дилетантсвом (коего я не стесняюсь, ибо любитель), или намек на то, что предыдущий совет плох?

Да, это был тонкий тролинг. 
Вам дали совет из книжки по программированию для линукса.
А на STM32, во-первых, ваша программа заглохнет уже на 5-и тысячах файлов,   во-вторых, Keil вам по умолчаню на malloc выделит всего 200! байт. :lol: 
Но даже если догадаетесь как выделить больше, все равно надо будет потратить кучу времени на выяснение этого максимума и нейтрализацию фрагментации. 
Поэтому чтобы бороться с такими проблемами ставят RTOS типа Azure RTOS и делают выделение памяти с таймаутом. 
Если такие операции с памятью идут очень часто ( каждую мс), то переходят ну уровень выше и используют пулы. 
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...