Source and destination overlap in memcpy



  • Hallo,

    ich wollte nur kurz fragen da valgrind es mir ankreidet meinen speicherbereich "umzuformen".
    Ich kopiere sozusagen einen hinteren teil in meinem heap-array an den anfang des heap-arrays. Ist das denn verboten oder sollte man sowas vermeiden?
    Mein Programm läuft einwandfrei...nur valgrind schreit da halt....

    Danke



  • Hallo,
    wenn du überlappende Speicherbereiche bearbeiten willst, musst du memmove benutzen, wenn du auf der sicheren Seite sein willst. Das Verhalten von memcpy ist nur für nicht-überlappende Speicherbereiche definiert.



  • memcpy ist dazu gedacht, Daten von einem Speicherbereich a nach Speicherbereich b zu kopieren. Wenn sich die Breiche ueberlappen, dann kopierst du zwangslaeufig etwas, was du direkt vorher beschrieben hast, bzw. verlierst etwas von deinen alten Informationen. Wierum das Kopieren vorgeht ist meines Wissens nicht festgelegt, daher ist das Ergebnis auch unklar. "Welcome to the dark shady realms of undefined behavior" 😉
    Ein Beispiel zur Veranschaulichung:

    |  Bereich a  |
          |  Bereich b  |
    1234567890abcde
    
    ==================
    memcpy(a, b, 15)
    ==================
    |  Bereich a  |
          |  Bereich b  |
          1234567890abcde  // von hinten nach vorne kopiert gehts
    ======ODER========
    |  Bereich a  |
          |  Bereich b  |
          123456123456123 // von vorn nach hinten: hier wurde die 7 schon vorher ueberschrieben!
    

    Ich denke das veranschaulicht es. Fuer solche Aufgaben mit ueberlapp gibts memmove, was die Werte zwischenspeichert.
    Oder man verxzichtet auf C-Routinen und simple Arrays, wenn moeglich.



  • da memove zwischenspeichert - ist es dann langsamer als memcpy ?

    seltsamerweise funktioniert es bei mir mit jedem input - es ist vielleicht dirty - aber solange memcpy schneller wäre als memove brauche ich memcpy ( oder ein redesign 😉 )



  • memmove kann langsamer sein, muss aber nicht.

    hier ist übrigens die komplett falsche stelle um auf geschwindigkeit zu achten: denn irgendwann wird memcpy hier fehlerhaft arbeiten und den fehler findest du dann sehr sehr lange nicht.



  • Mati schrieb:

    da memove zwischenspeichert - ist es dann langsamer als memcpy ?

    Es ist nicht notwendig, daß memmove() zwischenspeichert - das kann genausogut gelöst werden, indem es je nach Lage der Bereiche entscheidet, wahlweise von vorne oder von hinten mit dem Kopieren zu beginnen.


Anmelden zum Antworten