- SF800 Solar Speicher Tutorial         
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
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Hallo HaWe,

    wie Du getippt hast:
    Code:
    size_t len = 8;
    
    int16_t *ptr = (int16_t*)malloc(arrlen * sizeof(int16_t));
    
    /* Oder wenn's mit 0 initialisiert sein soll: *)
    ptr = (int16_t*)calloc(arrlen, sizeof(int16_t));
    ist die richtige Antwort.

    Allerdings ist es dann üblich mittels Pointer Arithemetik und nicht mit dem Array-Operator auf das Feld zuzugreifen also drittes Element im Feld;
    Code:
    *(ptr + 2) = 32 * 27 + *(ptr + 1);
    ist aber Geschmackssache.

  2. #2
    HaWe
    Gast
    ok, super, danke - hatte ich beide getestet, Fehler besteht fort, dann liegt es nicht an malloc.

    calloc kannte ich noch gar nicht, und es beantwortet eigtl sogar schon die nächste Frage, trotzdem, der Vollständigkeit halber:

    wenn ich mit
    buf = (int16_t *) malloc(arrlen*sizeof(int16_t) );
    den array angelegt habe, wie kann ich ihn manuell (nachträglich) mit Null initialisieren?

    Jetzt geht es also um memset...
    ist das hier korrekt:
    memset(buf, 0, sizeof(buf) );
    ...

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Nein, so geht's nicht, genau darin unterscheiden sich Arrays mit vorgegebener Größe gegenüber Speicherblöcken die mittels malloc & Co angelegt werden.
    sizeof(buf) gibt die Bytes für die Größe des Zeigers buf zurück. Der weiß nix über das was malloc & free so treiben.
    Code:
    memset(buf, 0, arrlen * sizeof(int16_t));
    wäre korrekt.

    Du mußt hier zwischen der Feldlänge die Du vorgibst und der Anzahl der Bytes, die sich immer aus 'Feldlänge mal Datenentypgröße' ergibt, unterscheiden.

  4. #4
    HaWe
    Gast
    ahaaa... da könnte der seltsame Fehler begründet sein, das muss ich jetzt mal testen.


    aber zu guter letzt, auch hier wieder die sizeof-Sache....:
    Thema memcpy:

    wenn ich einen array auf einen anderen kopieren will, habe ich bei statischen arrays verwendet
    memcpy(array1, array2, sizeof(array2) );

    nun ist array1 statisch und array2 ist dynamisch alloziert (mein buf).
    geht das nun stattdessen so...
    memcpy(array1, buf, arrlen * sizeof(int16_t) );
    ...

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Solange sizeof(array1) <= arrlen * sizeof(int16_t) ist und array1 vom typ int16_t ist - ja.

  6. #6
    HaWe
    Gast
    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) );

    ...

  7. #7
    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?

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    Zitat Zitat von HaWe Beitrag anzeigen
    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) );

    ...
    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

  9. #9
    HaWe
    Gast
    danke, mach ich so!

Ähnliche Themen

  1. Problem mit arrays in memset
    Von HaWe im Forum Arduino -Plattform
    Antworten: 0
    Letzter Beitrag: 05.06.2016, 12:39
  2. Tauchroboter (Fragen über Fragen)
    Von Michi Unfried im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 12
    Letzter Beitrag: 20.02.2014, 22: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, 19:25
  4. miniparser + malloc + speicherproblem?
    Von PCMan im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 09.01.2009, 15:03
  5. Fragen über Fragen - Schrittmotor
    Von Karierteshorts im Forum Motoren
    Antworten: 4
    Letzter Beitrag: 23.03.2005, 09:54

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress