Как установить размер массива в переменную, которая может измениться позже в коде?
Я пытаюсь глобально инициализировать массив, который может иметь разные размеры в соответствии с будущим кодом в Arduino.
инт п=0;
целое значение[n];
Это говорит о том, что связанный массив не является целочисленной константой перед токеном ']'. Это также говорит о том, что переменная val не была объявлена.
Я просматривал другие формы, и мне сказали использовать динамическое хранилище, но я не знаю, как это сделать.
Я пытаюсь сохранить в переменной разные значения веса, соответствующие времени. Сначала я попытался сохранить вес в одной переменной, но не смог найти общий вес и т. д.
@MegaTech, 👍-1
Обсуждение3 ответа
Платформа Arduino использует компилятор C/C++. В C++ можно использовать такие функции, как Векторы, чтобы создавать массивы различных размеров. Однако вполне вероятно, что при попытке таким образом абстрагировать использование памяти от приложения память тратится впустую. Во встроенной среде память, вероятно, имеет большое значение. Следовательно, почти всегда лучше обрабатывать размеры массивов во встроенных ситуациях, выделяя ожидаемую сумму вручную в начале программы.
Совет: если размер массива зависит от ситуации, в которой используется приложение, и в зависимости от приложения есть преимущества меньших массивов по сравнению с большими массивами, попробуйте использовать Условная компиляция для создания разных версий приложения.
Обычно массивы объявляются как
int array[n];
требуется постоянный размер n
, чтобы можно было выделить правильный размер памяти во время объявления. В противном случае компилятор не знает, что делать с этой переменной. Вы не можете изменить размер массива, особенно просто присваивая значения несуществующим элементам. Чтобы создать новый массив с размером, неизвестным во время компиляции, вам нужно будет использовать динамическое размещение:
int *array = new int[n];
Переменная array
на самом деле является не самим массивом, а указателем на целочисленный массив. Компилятор создаст переменную-указатель, которая будет содержать только адрес, где хранится новый динамически созданный массив. С помощью ключевого слова new
мы выделяем новое пространство памяти. С помощью int[n]
мы говорим программе выделить место для n
целых чисел. Вы можете создавать массивы с размерами, неизвестными во время компиляции, но вы не можете изменить размер массива. Вам нужно будет создать новый, чтобы изменить размер. Динамически выделенное хранилище, которое больше не нужно, должно быть освобождено. (Вы можете узнать больше об этом в Google)
НО: на Arduino вам не следует использовать динамическое выделение. Если вы слишком часто (снова и снова) используете динамическое выделение в программе, вы получите фрагментацию памяти. Когда вы выделяете и освобождаете память разного размера, вы получаете много небольших областей памяти, которые слишком малы для хранения ваших новых массивов. Таким образом, эта память теперь бесполезна, а у Arduino очень мало оперативной памяти, которую можно использовать для динамической памяти. Когда ваша оперативная память заполнена, ваша программа рухнет. Реальные компьютеры, напротив, имеют много памяти, так что это не проблема.
Лучше выделять память статически, оставляя достаточно места для обработки максимального ожидаемого объема данных. Таким образом, вы должны действительно подумать, действительно ли вам нужно динамическое распределение. Я бы сказал нет.
Есть и другие проблемы с вашим кодом.
Вы используете следующий цикл for:
for(n = 0; isFinished = true; n++)
Одиночный
=
отмечает назначение. Таким образом, в начале каждой итерации цикла for вы присваиваетеtrue
элементуisFinished
. И каждое задание будет оцениваться как верное. Итак, у вас есть бесконечный цикл. Если вы хотите проверить равенство, вам нужно использовать==
(двойной знак равенства). Также в цикле forisFinished
более новые изменения. Вы инициализируете его с помощьюfalse
, поэтому цикл не будет запускаться один раз. Если вы вместо этого проверите, чтобы она былаfalse
, цикл будет бесконечным, поскольку нет возможности, чтобы эта переменная изменилась внутри цикла. Вместо этого используйтеn
для условия цикла и запускайте цикл столько раз, сколько элементов в вашем массиве.Вообще ваша логика кажется непродуманной. Вы уже используете цикл for для измерения нескольких значений, так почему бы вам просто не измерить столько значений, сколько вы хотите измерить, используя цикл for, как описано выше. Тогда вам не нужны все элементы
isFinished
, потому что у вас всегда будут все необходимые значения при выходе из цикла for. Таким образом, вам также не нужно проверять, достаточно ли измеренных значений. И непонятно, что должна делать проверка порога.
Как уже отмечалось, динамическое выделение памяти часто создает проблемы на устройствах с нехваткой памяти, таких как Arduino. Когда вы создаете и освобождаете память, «куча» (пул памяти, который будет использоваться для этой цели) разбивается на «острова» свободной памяти с все еще используемыми блоками памяти, разбросанными повсюду.
В довольно короткие сроки доступная память становится практически непригодной для использования, в вашем приложении заканчивается доступная память, и ваше приложение аварийно завершает работу.
Это известно как "фрагментация кучи". Когда у вас есть только пара килобайт ОЗУ для работы, это быстро становится фатальным.
Если вы можете быть уверены, что выделяете динамический буфер в последовательности вызова функции, не выполняете никакого другого динамического выделения памяти, а затем освобождаете его перед возвратом, вы, вероятно, можете обойтись без фрагментации, но на самом деле вы нужно быть осторожным.
Если вместо этого вы динамически выделяете блок памяти на самом раннем этапе жизни вашего приложения, а затем сохраняете его на протяжении всего запуска, это тоже может быть нормально. Этот блок занимает часть вашей кучи и просто остается там.
Третья альтернатива – выделить во время компиляции массив статического размера, достаточно большой для наиболее частого использования, и рассматривать его как буфер. Вы можете сохранить содержимое там по мере необходимости, а затем, когда вы закончите с этим содержимым, использовать буфер для чего-то другого.
- Возможно ли иметь массив массивов int?
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
- Инициализация массива структур
- Невозможно создать массив типа const char*
- Работает ли конструкция int array[100] = {0} на Arduino?
- Массив динамического размера в качестве члена класса
- Длина константного массива uint8_t*
- Получение шестнадцатеричных данных с терминала
Пожалуйста, отредактируйте свой вопрос и добавьте код в «текстовом формате». На панели инструментов окна редактирования есть «кнопка», которая выглядит как
{}
. Выделите весь свой код и нажмите на него., @VE7JROДля меня это выглядит как [проблема XY](http://xyproblem.info/). Массив переменного размера не является реальной целью и, скорее всего, в первую очередь является плохой идеей. Какова ваша настоящая цель? Что вы пытаетесь достичь?, @Edgar Bonet
почему бы не использовать
int val[10]
илиint val[50]
?, @Juraj