16 KiB
zh_vector - Компонент вектора (динамического массива) для ESP-IDF
Содержание
- Обзор
- Возможности
- Установка
- Справочник API
- Примеры использования
- Технические характеристики
- Коды ошибок
- Вклад в проект
- Лицензия
Обзор
zh_vector — это легковесный и эффективный компонент вектора (динамического массива) для ESP-IDF (Espressif IoT Development Framework). Он предоставляет гибкий контейнер, который может хранить элементы любого типа данных с автоматическим управлением памятью. Вектор автоматически изменяет размер при добавлении или удалении элементов, что делает его идеальным для динамического управления данными во встраиваемых системах.
Компонент разработан специально для микроконтроллеров ESP32 и использует функции управления кучей ESP-IDF для оптимального выделения памяти с различными параметрами памяти (внутренняя/внешняя RAM).
Возможности
- Независимость от типа данных: Поддерживает любой тип данных (целые числа, числа с плавающей точкой, структуры, пользовательские типы и т.д.)
- Автоматическое управление памятью: Автоматическое выделение и освобождение памяти
- Динамическое изменение размера: Емкость вектора увеличивается и уменьшается по мере необходимости
- Максимальная емкость: До 65 535 элементов (ограничение 16-битного индекса)
- Оптимизировано под ESP-IDF: Использует функции heap_caps для выделения памяти с параметрами памяти
- Обработка ошибок: Комплексная проверка ошибок с детальным логированием
- Потокобезопасность: Не является потокобезопасным по умолчанию (можно сделать потокобезопасным с внешним мьютексом)
- Минимальные накладные расходы: Низкие накладные расходы на память и процессор
Установка
- Перейдите в каталог компонентов вашего проекта:
cd ../ваш_проект/components
- Клонируйте репозиторий:
git clone https://github.com/aZholtikov/zh_vector
- В вашем приложении подключите заголовочный файл:
#include "zh_vector.h"
- Компонент будет автоматически собран вместе с вашим проектом.
Справочник API
Структура zh_vector_t
typedef struct
{
void **items; // Массив указателей на элементы вектора
uint16_t capacity; // Максимальная емкость вектора
uint16_t size; // Количество элементов в векторе
uint16_t unit; // Размер элемента вектора (в байтах)
bool is_initialized; // Флаг состояния инициализации вектора
} zh_vector_t;
zh_vector_init()
Инициализирует вектор.
Параметры:
vector- Указатель на структуру вектораunit- Размер каждого элемента в байтах
Возвращает:
ESP_OK- УспехESP_ERR_INVALID_ARG- Неверный аргумент (NULL вектор или нулевой размер unit)ESP_ERR_INVALID_STATE- Вектор уже инициализирован
Пример:
zh_vector_t vector = {0};
zh_vector_init(&vector, sizeof(int)); // Для целых чисел
zh_vector_free()
Деинициализирует вектор и освобождает всю выделенную память.
Параметры:
vector- Указатель на структуру вектора
Возвращает:
ESP_OK- УспехESP_ERR_INVALID_ARG- Неверный аргумент (NULL вектор)ESP_ERR_INVALID_STATE- Вектор не инициализирован
Примечание: Вся динамически выделенная память элементов также освобождается.
zh_vector_get_size()
Получает текущее количество элементов в векторе.
Параметры:
vector- Указатель на структуру вектора
Возвращает:
>= 0- Количество элементов (успех)ESP_FAIL- Ошибка (NULL вектор или не инициализирован)
zh_vector_push_back()
Добавляет элемент в конец вектора.
Параметры:
vector- Указатель на структуру вектораitem- Указатель на элемент для добавления
Возвращает:
ESP_OK- УспехESP_ERR_INVALID_ARG- Неверный аргумент (NULL вектор или item)ESP_ERR_INVALID_STATE- Вектор не инициализированESP_ERR_NO_MEM- Ошибка выделения памяти
Примечание: Функция выделяет память для копии элемента и копирует данные.
zh_vector_change_item()
Изменяет элемент по определенному индексу.
Параметры:
vector- Указатель на структуру вектораindex- Индекс элемента для изменения (начиная с 0)item- Указатель на новые данные элемента
Возвращает:
ESP_OK- УспехESP_ERR_INVALID_ARG- Неверный аргумент (NULL вектор, item или неверный индекс)ESP_ERR_INVALID_STATE- Вектор не инициализированESP_FAIL- Индекс вне границ
zh_vector_get_item()
Получает элемент по определенному индексу.
Параметры:
vector- Указатель на структуру вектораindex- Индекс элемента для получения (начиная с 0)
Возвращает:
- Указатель на элемент (успех)
NULL- Ошибка (NULL вектор, не инициализирован или неверный индекс)
Примечание: Возвращает указатель на внутренние данные. Не освобождайте этот указатель.
zh_vector_delete_item()
Удаляет элемент по определенному индексу и сдвигает все последующие элементы.
Параметры:
vector- Указатель на структуру вектораindex- Индекс элемента для удаления (начиная с 0)
Возвращает:
ESP_OK- УспехESP_ERR_INVALID_ARG- Неверный аргумент (NULL вектор)ESP_ERR_INVALID_STATE- Вектор не инициализированESP_FAIL- Индекс вне границ
Примечание: Все элементы после удаляемого индекса сдвигаются влево на одну позицию.
Примеры использования
Базовый пример: Вектор целых чисел
#include "zh_vector.h"
zh_vector_t int_vector = {0};
void app_main(void)
{
esp_log_level_set("zh_vector", ESP_LOG_ERROR);
// Инициализация вектора для целых чисел
zh_vector_init(&int_vector, sizeof(int));
// Добавление элементов
int val1 = 10;
int val2 = 20;
int val3 = 30;
zh_vector_push_back(&int_vector, &val1);
zh_vector_push_back(&int_vector, &val2);
zh_vector_push_back(&int_vector, &val3);
printf("Размер вектора: %d\n", zh_vector_get_size(&int_vector));
// Доступ к элементам
for (int i = 0; i < zh_vector_get_size(&int_vector); i++) {
int *item = (int *)zh_vector_get_item(&int_vector, i);
printf("Элемент %d: %d\n", i, *item);
}
// Изменение элемента
int new_val = 100;
zh_vector_change_item(&int_vector, 1, &new_val);
// Удаление элемента
zh_vector_delete_item(&int_vector, 0);
// Очистка
zh_vector_free(&int_vector);
}
Пример со структурой
#include "zh_vector.h"
typedef struct {
int id;
char name[32];
float value;
} my_struct_t;
zh_vector_t struct_vector = {0};
void app_main(void)
{
esp_log_level_set("zh_vector", ESP_LOG_ERROR);
// Инициализация вектора для структур
zh_vector_init(&struct_vector, sizeof(my_struct_t));
// Добавление элементов-структур
my_struct_t item1 = {1, "Item 1", 1.5f};
my_struct_t item2 = {2, "Item 2", 2.5f};
zh_vector_push_back(&struct_vector, &item1);
zh_vector_push_back(&struct_vector, &item2);
// Доступ и модификация
my_struct_t *ptr = (my_struct_t *)zh_vector_get_item(&struct_vector, 0);
ptr->value = 10.5f;
// Очистка
zh_vector_free(&struct_vector);
}
Пример со строками (массивы символов)
#include "zh_vector.h"
#include "string.h"
zh_vector_t string_vector = {0};
void app_main(void)
{
esp_log_level_set("zh_vector", ESP_LOG_ERROR);
// Инициализация вектора для строк (макс. 100 символов)
char buffer[100] = {0};
zh_vector_init(&string_vector, sizeof(buffer));
// Добавление строк
strcpy(buffer, "Привет");
zh_vector_push_back(&string_vector, &buffer);
strcpy(buffer, "Мир");
zh_vector_push_back(&string_vector, &buffer);
// Печать всех строк
for (int i = 0; i < zh_vector_get_size(&string_vector); i++) {
char *str = (char *)zh_vector_get_item(&string_vector, i);
printf("Строка %d: %s\n", i, str);
}
// Очистка
zh_vector_free(&string_vector);
}
Технические характеристики
| Параметр | Значение |
|---|---|
| Максимальная емкость | 65 535 элементов |
| Тип индекса | uint16_t (16-бит) |
| Управление памятью | heap_caps_calloc, heap_caps_realloc, heap_caps_free |
| Параметры памяти | MALLOC_CAP_8BIT |
| Потокобезопасность | Не является потокобезопасным |
| Версия ESP-IDF | Тестировалось с v6.0.0 |
| Платформа | Серия ESP32 |
| Язык | C (C99) |
Коды ошибок
| Код ошибки | Описание |
|---|---|
ESP_OK |
Операция выполнена успешно |
ESP_ERR_INVALID_ARG |
Неверный аргумент (NULL указатель или нулевой размер) |
ESP_ERR_INVALID_STATE |
Вектор не инициализирован или уже инициализирован |
ESP_ERR_NO_MEM |
Ошибка выделения памяти (не хватает памяти) |
ESP_FAIL |
Общий сбой (например, индекс вне границ) |
Вклад в проект
Вклад приветствуется! Чтобы внести свой вклад:
- Сделайте форк репозитория
- Создайте ветку функции (
git checkout -b feature/AmazingFeature) - Закоммитьте ваши изменения (
git commit -m 'Add some AmazingFeature') - Отправьте в ветку (
git push origin feature/AmazingFeature) - Откройте Pull Request
Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию.
Лицензия
Этот проект лицензирован по лицензии Apache, версия 2.0 - см. файл LICENSE для подробной информации.
Apache License, Version 2.0
Авторское право (c) 2026 Алексей Жолтиков
Лицензировано по лицензии Apache License, Version 2.0 (далее — "Лицензия"); вы не можете использовать этот файл, кроме случаев, предусмотренных Лицензией. Копию Лицензии можно получить по адресу:
http://www.apache.org/licenses/LICENSE-2.0
Если иное не требуется действующим законодательством или не согласовано в письменном виде, программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ", БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. Смотрите Лицензию для получения конкретных прав и ограничений.
Дополнительные заметки
- Накладные расходы памяти: Каждый элемент требует дополнительной памяти для указателя во внутреннем массиве указателей
- Производительность: O(1) для получения/установки по индексу, O(n) для вставки/удаления в середине
- Лучшие практики:
- Всегда инициализируйте вектор перед использованием
- Освобождайте вектор по завершении, чтобы избежать утечек памяти
- Учитывайте ограничение максимального размера (65 535 элементов)
- Для обработки строк рассмотрите использование буферов фиксированного размера
Сгенерировано для zh_vector v1.1.1