From 21fbe83cb791960ed83283302d603153ee47b2df Mon Sep 17 00:00:00 2001 From: TD-er Date: Tue, 28 Jan 2025 14:49:27 +0100 Subject: [PATCH] [Memory] Fix freeing of allocated strings --- src/_C008.cpp | 2 +- src/_C010.cpp | 2 +- src/_C015.cpp | 2 +- src/_C016.cpp | 4 +-- src/_P055_Chiming.ino | 2 +- src/src/Commands/InternalCommands.cpp | 2 +- .../Controller_struct/C018_data_struct.cpp | 10 ++++---- .../ExtendedControllerCredentialsStruct.cpp | 3 ++- src/src/DataStructs/LogEntry.cpp | 7 +++--- src/src/DataStructs/LogStruct.h | 2 +- src/src/DataStructs/Modbus.cpp | 3 ++- src/src/DataStructs/RulesEventCache.cpp | 4 +++ src/src/DataStructs/Web_StreamingBuffer.cpp | 2 +- src/src/ESPEasyCore/ESPEasy_Log.cpp | 25 ++++++++++++------- src/src/Globals/RamTracker.cpp | 6 ++--- src/src/Helpers/Audio.cpp | 3 ++- src/src/Helpers/ESPEasy_checks.cpp | 2 +- src/src/Helpers/Memory.h | 6 ++++- src/src/Helpers/Modbus_RTU.cpp | 2 +- src/src/Helpers/StringConverter.cpp | 10 ++++++-- src/src/Helpers/StringConverter.h | 4 +++ src/src/Helpers/StringParser.cpp | 4 +-- src/src/Helpers/WebServer_commandHelper.cpp | 2 +- src/src/Helpers/_CPlugin_Helper.cpp | 3 ++- src/src/PluginStructs/P020_data_struct.cpp | 2 +- src/src/PluginStructs/P044_data_struct.cpp | 2 +- src/src/PluginStructs/P073_data_struct.cpp | 2 +- src/src/PluginStructs/P082_data_struct.cpp | 2 +- src/src/PluginStructs/P094_data_struct.cpp | 3 +-- src/src/PluginStructs/P104_data_struct.cpp | 4 +-- src/src/PluginStructs/P165_data_struct.cpp | 2 +- src/src/WebServer/ControlPage.cpp | 2 +- src/src/WebServer/RootPage.cpp | 4 +-- src/src/WebServer/ToolsPage.cpp | 4 +-- src/src/WebServer/UploadPage.cpp | 4 +-- src/src/WebServer/WebTemplateParser.cpp | 2 +- 36 files changed, 87 insertions(+), 58 deletions(-) diff --git a/src/_C008.cpp b/src/_C008.cpp index d7eb87dff0..4383f382fe 100644 --- a/src/_C008.cpp +++ b/src/_C008.cpp @@ -49,7 +49,7 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_TEMPLATE: { - event->String1 = String(); + free_string(event->String1); event->String2 = F("demo.php?name=%sysname%&task=%tskname%&valuename=%valname%&value=%value%"); break; } diff --git a/src/_C010.cpp b/src/_C010.cpp index c12ff0e60d..ec65589ad5 100644 --- a/src/_C010.cpp +++ b/src/_C010.cpp @@ -35,7 +35,7 @@ bool CPlugin_010(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_TEMPLATE: { - event->String1 = String(); + free_string(event->String1); event->String2 = F("%sysname%_%tskname%_%valname%=%value%"); break; } diff --git a/src/_C015.cpp b/src/_C015.cpp index e06d6eddac..5269e49733 100644 --- a/src/_C015.cpp +++ b/src/_C015.cpp @@ -202,7 +202,7 @@ bool CPlugin_015(CPlugin::Function function, struct EventStruct *event, String& if (!isvalid) { // send empty string to Blynk in case of error - formattedValue = String(); + free_string(formattedValue); } const String valueName = Cache.getTaskDeviceValueName(event->TaskIndex, x); diff --git a/src/_C016.cpp b/src/_C016.cpp index 625c377b0a..899446b438 100644 --- a/src/_C016.cpp +++ b/src/_C016.cpp @@ -104,8 +104,8 @@ bool CPlugin_016(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_TEMPLATE: { - event->String1 = String(); - event->String2 = String(); + free_string(event->String1); + free_string(event->String2); break; } diff --git a/src/_P055_Chiming.ino b/src/_P055_Chiming.ino index 1a45df5cb9..629b698d7a 100644 --- a/src/_P055_Chiming.ino +++ b/src/_P055_Chiming.ino @@ -529,7 +529,7 @@ uint8_t Plugin_055_ReadChime(const String& name, String& tokens) log = strformat(F("Chime: read %s "), fileName.c_str()); } - tokens = String(); + free_string(tokens); fs::File f = tryOpenFile(fileName, "r"); if (f) diff --git a/src/src/Commands/InternalCommands.cpp b/src/src/Commands/InternalCommands.cpp index b1c794eceb..450d759112 100644 --- a/src/src/Commands/InternalCommands.cpp +++ b/src/src/Commands/InternalCommands.cpp @@ -173,7 +173,7 @@ bool do_command_case_check(command_case_data & data, // The data struct is re-used on each attempt to process an internal command. // Re-initialize the only two members that may have been altered by a previous call. data.retval = false; - data.status = String(); + free_string(data.status); if (!checkSourceFlags(data.event->Source, group)) { data.status = return_incorrect_source(); diff --git a/src/src/Controller_struct/C018_data_struct.cpp b/src/src/Controller_struct/C018_data_struct.cpp index 16e1ce911a..91b3adb3b4 100644 --- a/src/src/Controller_struct/C018_data_struct.cpp +++ b/src/src/Controller_struct/C018_data_struct.cpp @@ -25,9 +25,9 @@ void C018_data_struct::reset() { delete C018_easySerial; C018_easySerial = nullptr; } - cacheDevAddr = String(); - cacheHWEUI = String(); - cacheSysVer = String(); + free_string(cacheDevAddr); + free_string(cacheHWEUI); + free_string(cacheSysVer); autobaud_success = false; } @@ -157,7 +157,7 @@ bool C018_data_struct::initOTAA(const String& AppEUI, const String& AppKey, cons if (myLora == nullptr) { return false; } bool success = myLora->initOTAA(AppEUI, AppKey, DevEUI); - cacheDevAddr = String(); + free_string(cacheDevAddr); C018_logError(F("initOTAA()")); updateCacheOnInit(); @@ -334,7 +334,7 @@ void C018_data_struct::updateCacheOnInit() { cacheDevAddr = myLora->sendRawCommand(F("mac get devaddr")); if (cacheDevAddr == F("00000000")) { - cacheDevAddr = String(); + free_string(cacheDevAddr); } } } diff --git a/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp b/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp index b536816798..2834cb7505 100644 --- a/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp +++ b/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp @@ -1,6 +1,7 @@ #include "../DataStructs/ExtendedControllerCredentialsStruct.h" #include "../Helpers/ESPEasy_Storage.h" +#include "../Helpers/StringConverter.h" #define EXT_CONTR_CRED_USER_OFFSET 0 #define EXT_CONTR_CRED_PASS_OFFSET 1 @@ -24,7 +25,7 @@ bool ExtendedControllerCredentialsStruct::validateChecksum() const void ExtendedControllerCredentialsStruct::clear() { for (size_t i = 0; i < CONTROLLER_MAX * 2; ++i) { - _strings[i] = String(); + free_string(_strings[i]); } } diff --git a/src/src/DataStructs/LogEntry.cpp b/src/src/DataStructs/LogEntry.cpp index 99348ce80c..0dffb03f9e 100644 --- a/src/src/DataStructs/LogEntry.cpp +++ b/src/src/DataStructs/LogEntry.cpp @@ -26,8 +26,9 @@ bool LogEntry_t::add(const uint8_t loglevel, const String& line) #endif // ifdef USE_SECOND_HEAP if (line.length() > LOG_STRUCT_MESSAGE_SIZE - 1) { - _message = std::move(line.substring(0, LOG_STRUCT_MESSAGE_SIZE - 1)); + move_special(_message, line.substring(0, LOG_STRUCT_MESSAGE_SIZE - 1)); } else { + reserve_special(_message, line.length()); _message = line; } } @@ -48,7 +49,7 @@ bool LogEntry_t::add(const uint8_t loglevel, String&& line) // Need to make a substring, which is a new allocation, on the 2nd heap HeapSelectIram ephemeral; #endif // ifdef USE_SECOND_HEAP - _message = move_special(line.substring(0, LOG_STRUCT_MESSAGE_SIZE - 1)); + move_special(_message, line.substring(0, LOG_STRUCT_MESSAGE_SIZE - 1)); } else { move_special(_message, std::move(line)); } @@ -59,7 +60,7 @@ bool LogEntry_t::add(const uint8_t loglevel, String&& line) void LogEntry_t::clear() { - _message = String(); + free_string(_message); _timestamp = 0; _loglevel = 0; } diff --git a/src/src/DataStructs/LogStruct.h b/src/src/DataStructs/LogStruct.h index 40930d22aa..4e3c644900 100644 --- a/src/src/DataStructs/LogStruct.h +++ b/src/src/DataStructs/LogStruct.h @@ -10,7 +10,7 @@ * LogStruct \*********************************************************************************************/ #ifdef ESP32 - #define LOG_STRUCT_MESSAGE_LINES 60 + #define LOG_STRUCT_MESSAGE_LINES 120 #else #ifdef USE_SECOND_HEAP #define LOG_STRUCT_MESSAGE_LINES 60 diff --git a/src/src/DataStructs/Modbus.cpp b/src/src/DataStructs/Modbus.cpp index 6c2e46ced1..a83796fbe0 100644 --- a/src/src/DataStructs/Modbus.cpp +++ b/src/src/DataStructs/Modbus.cpp @@ -4,6 +4,7 @@ #include "../DataStructs/ControllerSettingsStruct.h" #include "../ESPEasyCore/ESPEasy_Log.h" +#include "../Helpers/StringConverter.h" Modbus::Modbus() : ModbusClient(nullptr), errcnt(0), timeout(0), @@ -108,7 +109,7 @@ bool Modbus::handle() { unsigned int RXavailable = 0; #ifndef BUILD_NO_DEBUG - LogString = String(); + free_string(LogString); #endif int64_t rxValue = 0; diff --git a/src/src/DataStructs/RulesEventCache.cpp b/src/src/DataStructs/RulesEventCache.cpp index 743ad27037..e221c027c3 100644 --- a/src/src/DataStructs/RulesEventCache.cpp +++ b/src/src/DataStructs/RulesEventCache.cpp @@ -41,6 +41,10 @@ bool RulesEventCache::addLine(const String& line, const String& filename, size_t # ifdef USE_SECOND_HEAP HeapSelectDram ephemeral; # endif // ifdef USE_SECOND_HEAP + #ifdef ESP32 + reserve_special(event, event.length()); + reserve_special(action, action.length()); + #endif _eventCache.emplace_back(filename, pos, std::move(event), std::move(action)); return true; diff --git a/src/src/DataStructs/Web_StreamingBuffer.cpp b/src/src/DataStructs/Web_StreamingBuffer.cpp index 41203f8d7c..24e4905d67 100644 --- a/src/src/DataStructs/Web_StreamingBuffer.cpp +++ b/src/src/DataStructs/Web_StreamingBuffer.cpp @@ -336,7 +336,7 @@ void Web_StreamingBuffer::sendContentBlocking(String& data) { web_server.sendContent(data); if (data.length() > (CHUNKED_BUFFER_SIZE + 1)) { - data = String(); // Clear also allocated memory + free_string(data); // Clear also allocated memory } else { data.clear(); } diff --git a/src/src/ESPEasyCore/ESPEasy_Log.cpp b/src/src/ESPEasyCore/ESPEasy_Log.cpp index eade2faa67..fe82f366c8 100644 --- a/src/src/ESPEasyCore/ESPEasy_Log.cpp +++ b/src/src/ESPEasyCore/ESPEasy_Log.cpp @@ -17,6 +17,8 @@ #include "../Helpers/ESPEasy_Storage.h" #endif +#define UPDATE_LOGLEVEL_ACTIVE_CACHE_INTERVAL 5000 + /********************************************************************************************\ Init critical variables for logging (important during initial factory reset stuff ) \*********************************************************************************************/ @@ -124,6 +126,13 @@ bool loglevelActiveFor(uint8_t logLevel) { return false; } #endif + static uint32_t lastUpdateLogLevelCache = 0; + if (lastUpdateLogLevelCache == 0 || + timePassedSince(lastUpdateLogLevelCache) > UPDATE_LOGLEVEL_ACTIVE_CACHE_INTERVAL) + { + lastUpdateLogLevelCache = millis(); + updateLogLevelCache(); + } return logLevel <= highest_active_log_level; } @@ -143,15 +152,13 @@ uint8_t getSerialLogLevel() { } uint8_t getWebLogLevel() { - uint8_t logLevelSettings = 0; if (Logging.logActiveRead()) { - logLevelSettings = Settings.WebLogLevel; - } else { - if (Settings.WebLogLevel != 0) { - updateLogLevelCache(); - } + return Settings.WebLogLevel; + } + if (Settings.WebLogLevel != LOG_LEVEL_NONE) { + updateLogLevelCache(); } - return logLevelSettings; + return LOG_LEVEL_NONE; } bool loglevelActiveFor(uint8_t destination, uint8_t logLevel) { @@ -245,7 +252,7 @@ void addLog(uint8_t logLevel, const char *line) } } #else - if (!copy.reserve(strlen_P((PGM_P)line))) { + if (!reserve_special(copy, strlen_P((PGM_P)line))) { return; } copy = line; @@ -353,5 +360,5 @@ void addToLogMove(uint8_t logLevel, String&& string) Logging.add(logLevel, std::move(string)); } // Make sure the string may no longer keep up memory - string = String(); + free_string(string); } diff --git a/src/src/Globals/RamTracker.cpp b/src/src/Globals/RamTracker.cpp index 2e8ce55af7..874bfee834 100644 --- a/src/src/Globals/RamTracker.cpp +++ b/src/src/Globals/RamTracker.cpp @@ -156,7 +156,7 @@ RamTracker::RamTracker(void) { writePtr = 0; for (int i = 0; i < TRACES; i++) { - traces[i] = String(); + free_string(traces[i]); tracesMemory[i] = 0xffffffff; // init with best case memory values, so they get replaced if memory goes lower } @@ -172,7 +172,7 @@ void RamTracker::registerRamState(const String& s) { // store function int bestCase = bestCaseTrace(); // find best case memory trace if (ESP.getFreeHeap() < tracesMemory[bestCase]) { // compare to current memory value - traces[bestCase] = String(); + free_string(traces[bestCase]); readPtr = writePtr + 1; // read out buffer, oldest value first if (readPtr >= TRACEENTRIES) { @@ -210,7 +210,7 @@ void RamTracker::getTraceBuffer() { retval += ' '; retval += traces[i]; addLogMove(LOG_LEVEL_DEBUG_DEV, retval); - retval = String(); + retval.clear(); } } #endif // ifndef BUILD_NO_DEBUG diff --git a/src/src/Helpers/Audio.cpp b/src/src/Helpers/Audio.cpp index e7e8d115f7..1ee71cda51 100644 --- a/src/src/Helpers/Audio.cpp +++ b/src/src/Helpers/Audio.cpp @@ -5,6 +5,7 @@ #include "../Globals/RamTracker.h" #include "../Helpers/Hardware_GPIO.h" #include "../Helpers/Hardware_PWM.h" +#include "../Helpers/StringConverter.h" /********************************************************************************************\ @@ -53,7 +54,7 @@ void clear_rtttl_melody() { # endif // if FEATURE_RTTTL_EVENTS } - rtttlMelody = String(); + free_string(rtttlMelody); } void set_rtttl_melody(String& melody) { diff --git a/src/src/Helpers/ESPEasy_checks.cpp b/src/src/Helpers/ESPEasy_checks.cpp index 81340c09e3..7cb0789f07 100644 --- a/src/src/Helpers/ESPEasy_checks.cpp +++ b/src/src/Helpers/ESPEasy_checks.cpp @@ -211,7 +211,7 @@ String ReportOffsetErrorInStruct(const String& structname, size_t offset) { * Not a member function to be able to use the F-macro \*********************************************************************************************/ bool SettingsCheck(String& error) { - error = String(); + free_string(error); #ifndef LIMIT_BUILD_SIZE #ifdef esp8266 size_t offset = offsetof(SettingsStruct, ResetFactoryDefaultPreference); diff --git a/src/src/Helpers/Memory.h b/src/src/Helpers/Memory.h index 06d1a30459..9f7faab348 100644 --- a/src/src/Helpers/Memory.h +++ b/src/src/Helpers/Memory.h @@ -58,4 +58,8 @@ void *special_realloc(void *ptr, size_t size); void *special_calloc(size_t num, size_t size); -bool String_reserve_special(String& str, size_t size); \ No newline at end of file +// Perform a special memory allocate for the buffer pointer in the String object +// Allocation is tried either on 2nd heap (ESP8266) or PSRAM (ESP32) +// when possible. +bool String_reserve_special(String& str, size_t size); + diff --git a/src/src/Helpers/Modbus_RTU.cpp b/src/src/Helpers/Modbus_RTU.cpp index 7b3ac05ec3..7e452360cd 100644 --- a/src/src/Helpers/Modbus_RTU.cpp +++ b/src/src/Helpers/Modbus_RTU.cpp @@ -19,7 +19,7 @@ void ModbusRTU_struct::reset() { delete easySerial; easySerial = nullptr; } - detected_device_description = String(); + free_string(detected_device_description); for (int i = 0; i < 8; ++i) { _sendframe[i] = 0; diff --git a/src/src/Helpers/StringConverter.cpp b/src/src/Helpers/StringConverter.cpp index 6fb63f4456..eb4415a6bf 100644 --- a/src/src/Helpers/StringConverter.cpp +++ b/src/src/Helpers/StringConverter.cpp @@ -83,7 +83,7 @@ void move_special(String& dest, String&& source) { HeapSelectIram ephemeral; if (dest.reserve(source.length())) { dest = source; - source = String(); + free_string(source); return; } // Could not allocate on 2nd heap, so just move existing string @@ -106,6 +106,12 @@ bool reserve_special(String& str, size_t size) { return String_reserve_special(str, size); } +void free_string(String& str) { + // This is a call specifically tailored to what is done in: + // void String::move(String &rhs) + + String tmp(std::move(str)); +} /********************************************************************************************\ Format string using vsnprintf @@ -1515,7 +1521,7 @@ bool GetArgv(const char *string, String& argvString, unsigned int argc, char sep int pos_begin, pos_end; bool hasArgument = GetArgvBeginEnd(string, argc, pos_begin, pos_end, separator); - argvString = String(); + free_string(argvString); if (!hasArgument) { return false; } diff --git a/src/src/Helpers/StringConverter.h b/src/src/Helpers/StringConverter.h index de1ebfc581..61472b9541 100644 --- a/src/src/Helpers/StringConverter.h +++ b/src/src/Helpers/StringConverter.h @@ -58,6 +58,10 @@ String move_special(String&& source); // Try to reserve on the heap with the most space available bool reserve_special(String& str, size_t size); +// Arduino String does not have a function to de-allocate its internal buffer +// This is a special trick to de-allocate its internal buffer and thus free up memory. +void free_string(String& str); + /* template bool equals(const String& str, const T &val) { diff --git a/src/src/Helpers/StringParser.cpp b/src/src/Helpers/StringParser.cpp index 6f1eff7631..1a0e7b0f53 100644 --- a/src/src/Helpers/StringParser.cpp +++ b/src/src/Helpers/StringParser.cpp @@ -420,7 +420,7 @@ void transformValue( } if (equals(value, '0')) { - value = String(); + free_string(value); } else { const int valueLength = value.length(); @@ -769,7 +769,7 @@ bool findNextDevValNameInString(const String& input, int& startpos, int& endpos, move_special(format, valueName.substring(hashpos + 1)); move_special(valueName, valueName.substring(0, hashpos)); } else { - format = String(); + free_string(format); } deviceName.toLowerCase(); valueName.toLowerCase(); diff --git a/src/src/Helpers/WebServer_commandHelper.cpp b/src/src/Helpers/WebServer_commandHelper.cpp index 1a9092d22c..d8f37ded5e 100644 --- a/src/src/Helpers/WebServer_commandHelper.cpp +++ b/src/src/Helpers/WebServer_commandHelper.cpp @@ -23,7 +23,7 @@ HandledWebCommand_result handle_command_from_web(EventValueSource::Enum source, bool handledCmd = false; bool sendOK = false; - printWebString = String(); + free_string(printWebString); printToWeb = false; printToWebJSON = false; diff --git a/src/src/Helpers/_CPlugin_Helper.cpp b/src/src/Helpers/_CPlugin_Helper.cpp index 3d97c3b58b..347ff2e575 100644 --- a/src/src/Helpers/_CPlugin_Helper.cpp +++ b/src/src/Helpers/_CPlugin_Helper.cpp @@ -42,7 +42,8 @@ bool safeReadStringUntil(Stream & input, const unsigned long timer = start + timeout; unsigned long backgroundtasks_timer = start + 10; - str = String(); + // FIXME TD-er: Should this also de-allocate internal buffer? + str.clear(); do { // read character diff --git a/src/src/PluginStructs/P020_data_struct.cpp b/src/src/PluginStructs/P020_data_struct.cpp index 5b1b2bfcaa..3129576c6b 100644 --- a/src/src/PluginStructs/P020_data_struct.cpp +++ b/src/src/PluginStructs/P020_data_struct.cpp @@ -136,7 +136,7 @@ void P020_Task::discardClientIn() { } void P020_Task::clearBuffer() { - serial_buffer = String(); + free_string(serial_buffer); _maxDataGramSize = serial_processing == P020_Events::P1WiFiGateway ? P020_P1_DATAGRAM_MAX_SIZE : P020_DATAGRAM_MAX_SIZE; diff --git a/src/src/PluginStructs/P044_data_struct.cpp b/src/src/PluginStructs/P044_data_struct.cpp index 6db208ad24..f61fe04bbc 100644 --- a/src/src/PluginStructs/P044_data_struct.cpp +++ b/src/src/PluginStructs/P044_data_struct.cpp @@ -154,7 +154,7 @@ void P044_Task::clearBuffer() { maxMessageSize = _min(serial_buffer.length(), P044_DATAGRAM_MAX_SIZE); } - serial_buffer = String(); + free_string(serial_buffer); serial_buffer.reserve(maxMessageSize); } diff --git a/src/src/PluginStructs/P073_data_struct.cpp b/src/src/PluginStructs/P073_data_struct.cpp index 52daaa878c..008722e1b5 100644 --- a/src/src/PluginStructs/P073_data_struct.cpp +++ b/src/src/PluginStructs/P073_data_struct.cpp @@ -498,7 +498,7 @@ bool P073_data_struct::NextScroll() { } void P073_data_struct::setTextToScroll(const String& text) { - _textToScroll = String(); + free_string(_textToScroll); if (!text.isEmpty()) { const int bufToFill = getBufferLength(displayModel); diff --git a/src/src/PluginStructs/P082_data_struct.cpp b/src/src/PluginStructs/P082_data_struct.cpp index 354455ca8d..c51b682bf7 100644 --- a/src/src/PluginStructs/P082_data_struct.cpp +++ b/src/src/PluginStructs/P082_data_struct.cpp @@ -342,7 +342,7 @@ bool P082_data_struct::loop() { // Full sentence received # ifdef P082_SEND_GPS_TO_LOG _lastSentence = _currentSentence; - _currentSentence = String(); + free_string(_currentSentence); # endif // ifdef P082_SEND_GPS_TO_LOG completeSentence = true; available = easySerial->available(); diff --git a/src/src/PluginStructs/P094_data_struct.cpp b/src/src/PluginStructs/P094_data_struct.cpp index 268807bfcf..f0695bd374 100644 --- a/src/src/PluginStructs/P094_data_struct.cpp +++ b/src/src/PluginStructs/P094_data_struct.cpp @@ -594,7 +594,7 @@ bool P094_data_struct::loop() { for (size_t i = 0; i < length && valid; ++i) { if ((sentence_part[i] > 127) || (sentence_part[i] < 32)) { - sentence_part = String(); + free_string(sentence_part); ++sentences_received_error; valid = false; } @@ -653,7 +653,6 @@ const String& P094_data_struct::peekSentence() const { void P094_data_struct::getSentence(String& string, bool appendSysTime) { string = std::move(sentence_part); - sentence_part = String(); // FIXME TD-er: Should not be needed as move already cleared it. if (appendSysTime) { // Unix timestamp = 10 decimals + separator diff --git a/src/src/PluginStructs/P104_data_struct.cpp b/src/src/PluginStructs/P104_data_struct.cpp index 1b7e34e338..2f6e51a801 100644 --- a/src/src/PluginStructs/P104_data_struct.cpp +++ b/src/src/PluginStructs/P104_data_struct.cpp @@ -268,7 +268,7 @@ void P104_data_struct::loadSettings() { # endif // ifdef P104_DEBUG } - buffer = String(); // Free some memory + free_string(buffer); // Free some memory } delete[] settingsBuffer; // Release allocated buffer @@ -1676,7 +1676,7 @@ void P104_data_struct::checkRepeatTimer(uint8_t z) { * saveSettings gather the zones data from the UI and store in customsettings **************************************/ bool P104_data_struct::saveSettings() { - error = String(); // Clear + free_string(error); // Clear # ifdef P104_DEBUG_DEV diff --git a/src/src/PluginStructs/P165_data_struct.cpp b/src/src/PluginStructs/P165_data_struct.cpp index a7ceb8e1f7..c10cf930e2 100644 --- a/src/src/PluginStructs/P165_data_struct.cpp +++ b/src/src/PluginStructs/P165_data_struct.cpp @@ -2220,7 +2220,7 @@ bool P165_data_struct::nextScroll() { * Set up the string to scroll across the display, with optional prefixed spaces **********************************************************************************/ void P165_data_struct::setTextToScroll(const String& text) { - _textToScroll = String(); + free_string(_textToScroll); if (!text.isEmpty()) { const int bufToFill = calculateDisplayDigits(); diff --git a/src/src/WebServer/ControlPage.cpp b/src/src/WebServer/ControlPage.cpp index 5848d7d483..55efaaa810 100644 --- a/src/src/WebServer/ControlPage.cpp +++ b/src/src/WebServer/ControlPage.cpp @@ -41,7 +41,7 @@ void handle_control() { TXBuffer.endStream(); - printWebString = String(); + free_string(printWebString); printToWeb = false; printToWebJSON = false; } diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index a489a1e4f1..1e6085f3a8 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -274,7 +274,7 @@ void handle_root() { addHtml(F("Command Output
")); - printWebString = String(); + free_string(printWebString); } } html_end_table(); @@ -460,7 +460,7 @@ void handle_root() { # endif // if FEATURE_ESPEASY_P2P html_end_form(); - printWebString = String(); + free_string(printWebString); printToWeb = false; sendHeadandTail_stdtemplate(_TAIL); } diff --git a/src/src/WebServer/ToolsPage.cpp b/src/src/WebServer/ToolsPage.cpp index 26a861639b..908f8f971b 100644 --- a/src/src/WebServer/ToolsPage.cpp +++ b/src/src/WebServer/ToolsPage.cpp @@ -56,7 +56,7 @@ void handle_tools() { addHtml(F("Command Output
")); - printWebString = String(); + free_string(printWebString); } @@ -198,7 +198,7 @@ void handle_tools() { html_end_form(); sendHeadandTail_stdtemplate(_TAIL); TXBuffer.endStream(); - printWebString = String(); + free_string(printWebString); printToWeb = false; } diff --git a/src/src/WebServer/UploadPage.cpp b/src/src/WebServer/UploadPage.cpp index 072ba1a468..bb2a2e8697 100644 --- a/src/src/WebServer/UploadPage.cpp +++ b/src/src/WebServer/UploadPage.cpp @@ -35,7 +35,7 @@ void handle_upload() { "

Upload settings file:

")); sendHeadandTail_stdtemplate(_TAIL); TXBuffer.endStream(); - printWebString = String(); + free_string(printWebString); printToWeb = false; } @@ -87,7 +87,7 @@ void handle_upload_post() { addHtml(F("Upload finished")); sendHeadandTail_stdtemplate(_TAIL); TXBuffer.endStream(); - printWebString = String(); + free_string(printWebString); printToWeb = false; } diff --git a/src/src/WebServer/WebTemplateParser.cpp b/src/src/WebServer/WebTemplateParser.cpp index 3bc338c55a..afa20831d4 100644 --- a/src/src/WebServer/WebTemplateParser.cpp +++ b/src/src/WebServer/WebTemplateParser.cpp @@ -159,7 +159,7 @@ bool WebTemplateParser::process(const char c) { } else if (Tail == contentVarFound) { processVarName(); } - varName = String(); + free_string(varName); } } break;