Только начинаю работать с std::list в Arduino (компилятор C++ 11) Нужно положить в std::list класс:
class TTimerData : public Printable // для возможности прямой печати
{
public:
float t1;
float t2;
uint32_t time_on;
char _tt[20]; // для увеличения размера класса
String str;
TTimerData(float ptick1_ON, float ptick2_OFF, uint32_t ptime_on);
TTimerData( uint32_t ptime_on);
// операторы нужны для list.sort()
bool operator >(TTimerData const & a);
bool operator <(TTimerData const & a);
size_t printTo(Print& p) const;
};
Хранить в std::list можно двумя способами:
1 способ: хранить указатели на объекты:
typedef std::shared_ptr<TTimerData> TTimerDataPtr ;
typedef std::list<TTimerDataPtr> TTimerDataList;
Добавление элемента:
auto new_order = std::make_shared<TTimerData>(0,0,i);
lst.push_back(new_order);
shared_ptr нужны для автоматического освобождения памяти после удаления элемента из list.
2 способ: хранить сами объекты:
typedef std::list<TTimerData> TListInside;
Добавление:
lst.emplace_back(0,0,i); // создает объект внутри List и сразу вызывает конструктор TTimerData
ВОПРОС: какой способ хранения объекта в std::list предпочтительнее (ну или более правильный)?
Я провел в эксперимент, положил в list 200 объектов, в обоих случаях после удаления всех объектов из list ESP.getFreeContStack() и ESP.getFreeHeap() показывают значение, бывшее до момента добавления (т.е. утечки памяти нет)
Опасение у меня вызывает второй способ - когда вызывается метод lst.emplace_back(0,0,i); Я не совсем уверен что для выделения места он использует malloc - а не стек. list используется глобально и если память под новый объект выделяется в стеке - то ничего хорошего меня не ждет. Эксперимент правда показал, что malloc в этом случае используется, но полной уверенности у меня нет.
shared_ptr
нужны для автоматического освобождения памяти после удаления элемента
std::list
в любом случае сам освобождает память, которую занимал элемент, после его удаления. shared_ptr
для этого не нужен.
какой способ хранения объекта в std::list предпочтительнее
Если вам не нужны никакие особенности shared_ptr
, то лучше его не использовать.
Опасение у меня вызывает второй способ - когда вызывается метод lst.emplace_back(0,0,i);
Я не совсем уверен что для выделения места он использует malloc
- а не стек
Он никак не может использовать стек, только кучу. (Хотя скорее new
, а не malloc
.)
Память, которую функция выделяет в стеке, освобождается после выхода из функции. Если бы emplace_back
создавала новый объект на стеке, как бы она могла нормально работать? Этот новый объект уничтожался бы сразу после выхода из emplace_back
.
Крайне признателен @HolyBlackCat за весьма содержательную дискуссию.
Резюмируя вышеизложенное я пришел к выводу что лучше всего хранить сам объект непосредственно в list потому что данный способ не требует никакого дополнительного кода, память под объект выделяется и освобождается в куче а не в стеке.
Просто указатели на объект хранить в list нельзя - память под выделенные объекты освобождаться не будет. Для хранения указателей в list применяйте либо shared_ptr либо метод, предложенный @HolyBlackCat (требуется свой CustomAllocator + operator delete ) - на мой взгляд весьма большой кусок дополнительного кода.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Выполняется сортировка в потокахВ любой момент из переменной last_index я могу узнать сколько отсортированных элементов уже есть
Чтобы вытащить элементы из вектора в приоритетном порядке, кроме как сортировать вектор, можно еще превратить его в кучуВот такая простенькая...
Допустим, у меня есть много переменных с названием "a", я хочу их все переименовать в "b" во время редактирования кодаКак можно это быстро сделать?
Нужно ваша помощь по задаче на с++