From b1304f64cb66226cc3881bc2183e4fec92bbe322 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 12:56:53 -1000 Subject: [PATCH] avoid heap wifi scans --- esphome/components/wifi/wifi_component_esp_idf.cpp | 3 ++- esphome/core/helpers.h | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 848ec3e11c..2cd9ec452b 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -827,7 +827,8 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { } uint16_t number = it.number; - auto records = std::make_unique(number); + // Stack buffer for up to 38 APs (~3.5KB), heap fallback for dense environments + SmallBufferWithHeapFallback<38, wifi_ap_record_t> records(number); err = esp_wifi_scan_get_ap_records(&number, records.get()); if (err != ESP_OK) { ESP_LOGW(TAG, "esp_wifi_scan_get_ap_records failed: %s", esp_err_to_name(err)); diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 7de952a712..eaf3ffb877 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -371,13 +371,15 @@ template class FixedVector { /// @brief Helper class for efficient buffer allocation - uses stack for small sizes, heap for large /// This is useful when most operations need a small buffer but occasionally need larger ones. /// The stack buffer avoids heap allocation in the common case, while heap fallback handles edge cases. -template class SmallBufferWithHeapFallback { +/// @tparam STACK_SIZE Number of elements in the stack buffer +/// @tparam T Element type (default: uint8_t) +template class SmallBufferWithHeapFallback { public: explicit SmallBufferWithHeapFallback(size_t size) { if (size <= STACK_SIZE) { this->buffer_ = this->stack_buffer_; } else { - this->heap_buffer_ = new uint8_t[size]; + this->heap_buffer_ = new T[size]; this->buffer_ = this->heap_buffer_; } } @@ -389,12 +391,12 @@ template class SmallBufferWithHeapFallback { SmallBufferWithHeapFallback(SmallBufferWithHeapFallback &&) = delete; SmallBufferWithHeapFallback &operator=(SmallBufferWithHeapFallback &&) = delete; - uint8_t *get() { return this->buffer_; } + T *get() { return this->buffer_; } private: - uint8_t stack_buffer_[STACK_SIZE]; - uint8_t *heap_buffer_{nullptr}; - uint8_t *buffer_; + T stack_buffer_[STACK_SIZE]; + T *heap_buffer_{nullptr}; + T *buffer_; }; ///@}