- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 32

Thema: C: Fragen zu memset, memcpy, malloc

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo HaWe,
    Zitat Zitat von HaWe Beitrag anzeigen
    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) );
    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!

    Code:
    ptr = malloc(size);
    if (ptr )
      {
         // du kannst mit ptr arbeiten
      }
    else
      {
        // Fehler: kein Platz auf dem Heap
      }
    zudem habe ich mir auch angewöhnt:
    Code:
      free(ptr);
      ptr = NULL;
    Meist macht zumindest die Debug-Version einen Test auf NULL-Pointer, somit bekommst du beim Debuggen eine Fehlermeldung.
    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?

  2. #2
    HaWe
    Gast
    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?

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Zitat Zitat von HaWe Beitrag anzeigen
    super Tipps, vor allem das mit dem malloc Rückgabewert und dem Nullpointer nach free()!
    Hat sich bei mir die letzten 25 Jahre so bewährt.
    Zitat Zitat von HaWe Beitrag anzeigen
    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?
    Jo!

    Da für C alles !=0 als TRUE definiert ist, kann man auch verkürzt
    if (buf) {...}
    schreiben.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  4. #4
    HaWe
    Gast
    perfekt, danke!

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    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)

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    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.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    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);
    }

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Das sind spezielle Überladungen, die kommen bei normalem Anfordern von Speicher nicht zum Einsatz. Es handelt sich um sowas hier:
    https://en.wikipedia.org/wiki/Placement_syntax

    Man kann in C++ ja sowas machen
    Code:
        #include <new>        // Must #include this to use "placement new"
        #include "Fred.h"     // Declaration of class Fred
        void someCode()
        {
          char memory[sizeof(Fred)];     // Line #1
          void* place = memory;          // Line #2
          Fred* f = new(place) Fred();   // Line #3 (see "DANGER" below)
          // The pointers f and place will be equal
          // ...
        }
    das ist eine andere Baustelle.


    Im übrigen ist es meist so, dass new und delete auf malloc und free zurückgreifen, oder auf die Betriebssystemfunktionen die diesese beiden verwenden.

    Aber new und delete rufen auch Konstruktor und Destruktor der angelegten Objekte auf. Ein malloc würde nur Speicher anfordern, das Objekt darin aber nicht initialisieren. Ein free auf etwas mit new angefordertem würde einem Objekt den Speicher klauen, läuft doch später noch der Destruktor knallt es, usw.
    Geändert von Mxt (29.06.2016 um 08:24 Uhr)

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Interessant, schaue ich mir demnächst mal genauer an...

Ähnliche Themen

  1. Problem mit arrays in memset
    Von HaWe im Forum Arduino -Plattform
    Antworten: 0
    Letzter Beitrag: 05.06.2016, 11:39
  2. Tauchroboter (Fragen über Fragen)
    Von Michi Unfried im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 12
    Letzter Beitrag: 20.02.2014, 21:03
  3. Rasenmähroboter fragen zur lenkung und mehr fragen :-)
    Von andiwalter im Forum Staubsaugerroboter / Reinigungs- und Rasenmähroboter
    Antworten: 11
    Letzter Beitrag: 11.05.2009, 18:25
  4. miniparser + malloc + speicherproblem?
    Von PCMan im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 09.01.2009, 14:03
  5. Fragen über Fragen - Schrittmotor
    Von Karierteshorts im Forum Motoren
    Antworten: 4
    Letzter Beitrag: 23.03.2005, 08:54

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test