diff --git a/esphome/components/mdns/mdns_esp32.cpp b/esphome/components/mdns/mdns_esp32.cpp index 7704c1d649..b03455ea2f 100644 --- a/esphome/components/mdns/mdns_esp32.cpp +++ b/esphome/components/mdns/mdns_esp32.cpp @@ -26,16 +26,24 @@ void MDNSComponent::setup() { mdns_instance_name_set(this->hostname_.c_str()); for (const auto &service : this->services_) { - std::vector txt_records(service.txt_records.size()); - for (size_t i = 0; i < service.txt_records.size(); i++) { - // mdns_service_add copies the strings internally, no need to strdup - txt_records[i].key = service.txt_records[i].key.c_str(); - txt_records[i].value = const_cast &>(service.txt_records[i].value).value().c_str(); + std::vector txt_records; + for (const auto &record : service.txt_records) { + mdns_txt_item_t it{}; + // key is a persistent string in services_, no need to strdup + it.key = record.key.c_str(); + // value is a temporary from TemplatableValue, must strdup to keep it alive + it.value = strdup(const_cast &>(record.value).value().c_str()); + txt_records.push_back(it); } uint16_t port = const_cast &>(service.port).value(); err = mdns_service_add(nullptr, service.service_type.c_str(), service.proto.c_str(), port, txt_records.data(), txt_records.size()); + // free records + for (const auto &it : txt_records) { + free((void *) it.value); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-pro-type-cstyle-cast) + } + if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to register service %s: %s", service.service_type.c_str(), esp_err_to_name(err)); }