Как указать длину массива при построении объекта в Arduino IDE?

Я работаю над групповым проектом по созданию собственной библиотеки с использованием Arduino IDE. Поскольку среда разработки Arduino использует C++, библиотека должна быть классом. Одно из полей класса представляет собой массив чисел. Нам бы хотелось, чтобы мы могли указать длину массива во время построения объекта, поскольку есть плюсы и минусы для малой и большой длины массива. Можно ли указать или изменить длину массива при построении объекта?

К сожалению, среда разработки Arduino IDE не позволяет использовать векторы C++, поэтому об этом не может быть и речи.

, 👍1

Обсуждение

Библиотека Arduino не обязательно должна быть классом, @Juraj

Это не исключено. Существуют различные порты STL (стандартной библиотеки шаблонов) для Arduino. Попробуйте поискать их. Arduino IDE сама по себе не исключает их использования., @Nick Gammon


3 ответа


Лучший ответ:

0

Как предложено в st2000 ответ, вы можете использовать динамическое размещение, но если вы это сделаете, не забудьте освободить выделенная память в деструкторе. Иначе у тебя скверная память утечка и ваша программа долго не проживет:

class MyClass {
public:
    MyClass(size_t length) : arrayLength(length) {
        theArrayOfNumbers = new int[arrayLength];
    }
    ~MyClass() {
        delete[] theArrayOfNumbers;
    }
private:
    const size_t arrayLength;
    int *theArrayOfNumbers;
};

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

Более безопасным вариантом было бы использовать класс шаблона. Таким образом массив размещен статически:

template <size_t arrayLength>
class MyTemplateClass {
    int theArrayOfNumbers[arrayLength];
};

Одно предостережение при таком подходе заключается в том, что пользователи библиотеки не могут быть удобным с синтаксисом для создания экземпляра шаблона. Вы будете должны предоставить четкие примеры в документации. Другая проблема заключается в что размер массива должен быть константой времени компиляции.

,

* Как было предложено в предыдущем ответе * - лучше дать ссылку на ответ. В Stack Exchange нет такого понятия, как постоянное «предыдущее». Порядок ответов зависит от голосования. Каждый ответ имеет ссылку **поделиться**, которую можно использовать для получения подходящей ссылки на него., @Nick Gammon

примечание: для каждого использования шаблона с другим размером компилятор генерирует другой класс. каждый класс занимает место в памяти программы, @Juraj

@NickGammon: Хороший вопрос. Добавил ссылку., @Edgar Bonet

Память, выделенная с помощью new[], должна быть удалена с помощью delete[], а не delete., @tttapa

тттапа прав. Эта строка должна выглядеть так: delete [] theArrayOfNumbers;, @Nick Gammon

Ой! Виноват. Оказывается, с avr-gcc операторы delete и операторы delete[] реализованы так же, как и jmp free. Но тогда, конечно, на это не стоит полагаться. Я исправил ответ., @Edgar Bonet


0

Некоторые примеры решений можно найти в этом вопросе/ответе по обмену стеками. В принятом ответе использовался этот код:

private int size;

private String words[];

public WordStore(int n){
     words =new String[n];
}
,

и освободить выделенную память? и предотвратить быструю фрагментацию памяти?, @Juraj

Действительно хорошие моменты @Juraj, я бы добавил их, но Эдгар уже привел хорошие примеры. Спасибо., @st2000


3

Другой способ заключается в том, чтобы вызывающая сторона предоставила память в качестве указателя на достаточное количество байтов для N объектов (при необходимости приводя к указателю на требуемый тип) и число N таких объектов. Это дает вызывающему объекту выбор: распределять ресурсы статически или динамически.

Похоже, вам нужен массив целых чисел. Таким образом, вы должны выделить массив (статически, в моем примере, но вы можете выбрать то, что лучше всего подходит для вашего приложения):

int memArray[N];
// ...
myClass(N, memArray&);

Я избегаю выделения памяти из кучи, но у кого-то могут быть другие предпочтения или ситуации, требующие этого; этот метод позволяет библиотеке работать в обоих случаях.

,