Solange sizeof(array1) <= arrlen * sizeof(int16_t) ist und array1 vom typ int16_t ist - ja.
Solange sizeof(array1) <= arrlen * sizeof(int16_t) ist und array1 vom typ int16_t ist - ja.
genau so ist es (beide arrays sind eigentlich gleich groß) -
perfekt, danke!
nun noch eine allerletzte Frage, ebenfalls wieder zu memset:
für den Fall, dass ich meinen dynamischen buf initialisieren will mit 128 statt mit 0, dann wäre doch vermutlich dieser Befehl dann auch richtig...
memset( buf, 128, arrlen*sizeof(int16_t) );
...![]()
Hallo HaWe,
Richtig!
wie schon geschrieben wurde:
sizeof(Datentyp)
Gibt immer die Grösse in Bytes zurück. Dazu muss aber zur Compiltime die Grösse bekannt sein.
malloc(), memset(), mem...()
arbeiten ALLE mit der Byte-Anzahl, die haben keine Ahnung von Datentypen und deren Grösse.
calloc() macht die Multiplikation "sizeof() * n" selbst und ruft memset() mit 0 auf.
Grundsätzlich ist es egal ob du mit statischen Variablen oder welchen auf dem Heap arbeitest. Zeiger ist Zeiger, aber er muss auf einen gültigen Bereich zeigen!
Bei Variablen auf dem Heap bist du aber selbst verantwortlich, dass du nicht über den Rand der Variablen zugreifst, da kann dir der Compiler nicht helfen.
Daher kann man den Heap auch leicht zerschiessen.
Der Heap besteht meistens aus einer verketteten Liste. Die Informationen für die Verkettung liegt auf den Adressen vor dem Speicher, welcher dir malloc() liefert. Schreibst du hinter den dir zugesicherten Bereich, überschreibst du die Infos für die verkettete Liste des nächsten Blocks, dann kommt die Heap-Verwaltung durcheinander mit den lustigsten Effekten
Unsauber an deinem Code ist noch, dass man den Rückgabewert von malloc() überprüfen sollte!
Wenn kein Platz auf den Heap ist, liefert malloc() NULL als Rückgabewert!
zudem habe ich mir auch angewöhnt:Code:ptr = malloc(size); if (ptr ) { // du kannst mit ptr arbeiten } else { // Fehler: kein Platz auf dem Heap }
Meist macht zumindest die Debug-Version einen Test auf NULL-Pointer, somit bekommst du beim Debuggen eine Fehlermeldung.Code:free(ptr); ptr = NULL;
Je nach CPU und deren Speicherverwaltung, löst ein Schreibzugriff mit einem NULL-Pointer einen Exception-Interrupt aus.
Wenn man einen NULL-Pointer mit free() ist garantiert, dass free() nichts macht.
Gibt man einen bereits zurückgegebenen Block nochmals mit free() zurück, oder man übergibt free() irgendeinen Wert, zerschiesst du meistens der Heap, auf alle Fälle sind das dann oft schwer zu findende Fehler
Zur Laufzeit ist die Anordnung auf den Heap mehr oder weniger zufällig, weshalb sich solche Fehler oft auch nicht richtig reproduzieren lassen.
Ein häufiger Fehler ist auch, dass vergessen wird den Block mit free() an den Heap zurück zu geben. Dann geht dir irgendwann der freie Speicher aus und malloc() liefert NULL.
MfG Peter(TOO)
Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?
super Tipps, vor allem das mit dem malloc Rückgabewert und dem Nullpointer nach free()!
Werde ich genau so machen, vielen Dank !
edit:
für
buf = (int16_t *)malloc(arrlen * sizeof (int16_t) );
heißt das dann
if(buf!=NULL) {...}
bzw.
if(buf==NULL) {
Serial.print("\n\n malloc() error - not enough memory\nprogram halted\n\n");
return;
}
richtig?
perfekt, danke!
Tipp: Um den Code lesbarer zu machen, Makros verwenden:
[Geschmacksache]
Code:#define int16_malloc(len) (int16_t*)malloc(len*sizeof(int16_t)) #define delete(ptr) free(ptr);ptr=NULL int main() { int16_t* buf = int16_malloc(24); // 24 * int16 allokieren if(buf) { //... was mit buf anstellen delete(buf); } ... }
Geändert von Sisor (28.06.2016 um 20:54 Uhr)
Vorsicht bei dem Namen "delete" für ein Makro.
Da HaWe und andere hier meist einen C++ Compiler benutzen um darin C zu machen. Das klein geschriebene delete ist ein reserviertes Wort in C++. Daher gibt es die Konvention Makros möglichst immer GROSS zu schreiben.
malloc und free sind in C++ eigentlich nur zur Rückwärtskompatibilität mit C vorhanden. Wenn man free auf einem Zeiger ausführt, der auf mit new angeforderten Speicher zeigt, oder andersrum aus Versehen delete auf mit malloc angeforderten Speicher aufruft, dann kann das Programm ganz plötzlich zuende sein.
Das ist wohl richtig. Für c++ würde ich Makros auch nicht empfehlen.
Hier mal ein Auszug aus dem Arduino-Kern. Implementation von new und delete [new.cpp]:
Code:#include <stdlib.h> void *operator new(size_t size) { return malloc(size); } void *operator new[](size_t size) { return malloc(size); } void operator delete(void * ptr) { free(ptr); } void operator delete[](void * ptr) { free(ptr); }
Nur wenn du in JEDES Byte 128 schreiben willst. Wenn du in jedes Feld (2 Byte <-> int16) 128 schreiben willst, funktioniert das nicht mehr!
Und der Rückgabewert von malloc() wird für gewöhnlich nicht gecastet. http://stackoverflow.com/questions/6...sult-of-malloc
mfg
Lesezeichen