Ich bin nicht einverstanden mit Leuten, die denken, man sollte es nicht benutzen oder es ist im Allgemeinen unnötig. Ich glaube, es kann gefährlich sein, wenn Sie nicht genau wissen, wie es aussieht, aber es ist nützlich. Es gibt Fälle, in denen ich die Größe einer Struktur oder eines Puffers (zur Kompilier- oder Laufzeit) nicht kenne (und auch nicht wissen sollte), insbesondere wenn es um Bibliotheken geht, die ich in die Welt versende. Ich bin damit einverstanden, dass Sie beim Kompilieren nur in dieser Größe backen sollten, wenn es sich bei Ihrer Anwendung nur um eine einzige bekannte Struktur handelt.
Beispiel: Ich habe eine serielle Paketklasse (eine Bibliothek), die Nutzdaten beliebiger Länge aufnehmen kann (Struktur, Array von uint16_t usw.). Am Ende dieser Klasse teilen Sie der Packet.send () -Methode einfach die Adresse des zu sendenden Objekts und den HardwareSerial-Port mit, über den Sie es senden möchten. Auf der Empfängerseite benötige ich jedoch einen dynamisch zugewiesenen Empfangspuffer, um die eingehende Nutzlast zu speichern, da diese Nutzlast zu jedem Zeitpunkt eine andere Struktur haben kann, zum Beispiel abhängig vom Status der Anwendung. WENN ich jemals nur eine einzelne Struktur hin und her sende, würde ich den Puffer einfach auf die Größe bringen, die er zum Zeitpunkt der Kompilierung haben muss. Aber in dem Fall, dass Pakete im Laufe der Zeit unterschiedlich lang sein können, sind malloc () und free () nicht so schlecht.
Ich habe tagelang Tests mit dem folgenden Code ausgeführt und ihn in einer Endlosschleife laufen lassen, und ich habe keine Hinweise auf eine Speicherfragmentierung gefunden. Nach dem Freigeben des dynamisch zugewiesenen Speichers kehrt der freie Betrag zu seinem vorherigen Wert zurück.
// found at learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
uint8_t *_tester;
while(1) {
uint8_t len = random(1, 1000);
Serial.println("-------------------------------------");
Serial.println("len is " + String(len, DEC));
Serial.println("RAM: " + String(freeRam(), DEC));
Serial.println("_tester = " + String((uint16_t)_tester, DEC));
Serial.println("alloating _tester memory");
_tester = (uint8_t *)malloc(len);
Serial.println("RAM: " + String(freeRam(), DEC));
Serial.println("_tester = " + String((uint16_t)_tester, DEC));
Serial.println("Filling _tester");
for (uint8_t i = 0; i < len; i++) {
_tester[i] = 255;
}
Serial.println("RAM: " + String(freeRam(), DEC));
Serial.println("freeing _tester memory");
free(_tester); _tester = NULL;
Serial.println("RAM: " + String(freeRam(), DEC));
Serial.println("_tester = " + String((uint16_t)_tester, DEC));
delay(1000); // quick look
}
Ich habe keine Beeinträchtigung des Arbeitsspeichers oder meiner Fähigkeit, ihn mithilfe dieser Methode dynamisch zuzuweisen, festgestellt. Daher würde ich sagen, dass dies ein praktikables Tool ist. FWIW.