Ciao a tutti!!!
Sono consapevole che l'utilizzo della classe "String" con la S maiuscola molti dicono che è il MALE ASSOLUTO poiché, se non gestito bene, può causare frammentazione della memoria RAM, soprattutto se si usano microcontrollori con poca memoria come l'ATMEGA328 e altri suoi simili...
Sto già provando altre alternative come le stringhe fatte nel "classico" modo ovvero con gli array, ma l'intento di questo post è ricevere delle delucidazioni nel caso ho desiderio di continuare ad utilizzare la classe String sia perché, se è stata realizzata, dovrebbe avere un suo senso e quindi utilizzarla al meglio evitando pasticci ![]()
Detto questo ho dei dubbi che in parte sono riuscito a capire leggendo un po' da vari forum, dove in alcuni ho preso spavento tipo questo:
[The Evils of Arduino Strings]
(The Evils of Arduino Strings | Majenko's Hardware Hacking Blog)
E in altri dove "tranquillizzano" di più l'uso:
[String class warning on Arduino forum]
(String class warning on Arduino forum | Teensy Forum)
Ho usato anche chatGPT e non ho notato grandi differenze, cioè non sembra che mi abbia detto cose sbagliate riguardo all'utilizzo della classe "String".
Nei miei progetti non ho mai utilizzato più di una variabile Stringa globale proprio perché sapevo in maniera generale sul fatto che allocasse dinamicamente il proprio spazio sulla RAM.
L'utilizzo principale è sempre e SOLO stato il ricevimento dei dati da parte della funzione:
Serial.readStringUntil(), e di conseguenza la comparazione di essa per gestire messaggi seriali dal programma.
Finora, nonostante programmi alquanto complessi, non ho mai ottenuto problemi di prestazioni anche perché tutti i protocolli che ho costruito non hanno mai richiesto messaggi complessi; cioè, sono sempre riuscito a gestire la stringa con messaggi di meno di 16 caratteri e non ha mai avuto di più.
Ho imparato ad usare la funzione "String.reserve()" per la variabile globale in maniera tale che mi allochi sempre all'inizio uno spazio riservato per essa sapendo che i messaggi non saranno mai più grandi e quindi nessuna nuova riallocazione... ALMENO SPERO ![]()
DUBBIO PRINCIPALE:
Quando si utilizza la funzione: Serial.readStringUntil() ho visto al suo interno, nel file "Stream.cpp", che ha una variabile Stringa temporanea.
Da questo sono rimasto dubbioso perché essendo temporanea significa che viene ogni volta allocato uno spazio e deallocato per trasferire il messaggio sulla variabile globale esterna (progetto dell'utente).
Quello che mi chiedo é: se in tutto il progetto è l'unica variabile Stringa temporanea che ogni volta che la funzione viene eseguita viene creata e riaggiornata come nuova alla prossima chiamata, succede che avrò una evitabile frammentazione della memoria?
E' peggio avere una variabile String di tipo temporaneo all'interno di una funzione?
O ogni volta che viene deallocata la sua entità, il suo oggetto sparisce e la memoria HEAP è libera per ricevere altre allocazioni?
Se quello che penso è vero non capisco il senso di tale funzione, significa che ad ogni chiamata frammenta la memoria e spero mi sbaglio ![]()
Questo vale anche per funzioni che accettano un parametro di tipo Stringa: il passaggio del messaggio avviene creando una allocazione temporanea nell'HEAP per poi essere deallocata? O in questo caso entra in gioco la memoria STACK ? ![]()
O la classe String è stata progettata con un minimo di gestione per semplici casi come questo?
SECONDO DUBBIO:
Se uso la funzione "reserve()" per l'unica Stringa nel programma e inserisco un messaggio formato sempre da meno caratteri di quanto sia lo spazio allocato con "reserve()" non dovrei avere nessuna riallocazione? Giusto?
E finché userò messaggi variabili ma sempre formati da caratteri minori del numero dello spazio allocato con "reserve()" non dovrei avere nuove allocazioni? Giusto?
Perché ho letto che i problemi ci sono quando vengono eseguite concatenazioni e quindi nuove allocazioni e di conseguenza la probabile e inevitabile creazione di "buchi" nella memoria HEAP ![]()
Grazie a tutti in ANTICIPO ![]()