memcpy vs. memmove
-
According to the documentation, memcpy does not guarantee the result if the source and destination overlap; on the other hand, memmove will graciously handle the case, by coping first the overlapping region. Consider the following example : char szTempCpy[] = "this is the most reliable test"; char szTempMov[] = "this is the most reliable test"; memcpy( szTempCpy + 5, szTempCpy, 25); memmove( szTempMov + 5, szTempMov, 25); printf("memcpy : %s\nmemmove : %s\n", szTempCpy, szTempMov); Now, when this is compiled in release you will get the correct behavior : memcpy will trash the data ( the ouput is "this this this this ...") and memmove will get it right ( "this this is the most ..."). The surprise comes when you compile debug : both memcpy and memmove will yield the same result ( the correct one ) - "this this is the most ...". Does anybody have a good explanation for this ?
-
According to the documentation, memcpy does not guarantee the result if the source and destination overlap; on the other hand, memmove will graciously handle the case, by coping first the overlapping region. Consider the following example : char szTempCpy[] = "this is the most reliable test"; char szTempMov[] = "this is the most reliable test"; memcpy( szTempCpy + 5, szTempCpy, 25); memmove( szTempMov + 5, szTempMov, 25); printf("memcpy : %s\nmemmove : %s\n", szTempCpy, szTempMov); Now, when this is compiled in release you will get the correct behavior : memcpy will trash the data ( the ouput is "this this this this ...") and memmove will get it right ( "this this is the most ..."). The surprise comes when you compile debug : both memcpy and memmove will yield the same result ( the correct one ) - "this this is the most ...". Does anybody have a good explanation for this ?
the memcpy function has this little bit at the front:
; Check for overlapping buffers:
; If (dst <= src) Or (dst >= src + Count) Then
; Do normal (Upwards) Copy
; Else
; Do Downwards Copy to avoid propagation
mov eax,ecx ;V - eax = byte count...mov edx,ecx ;U - edx = byte count... add eax,esi ;V - eax = point past source end cmp edi,esi ;U - dst <= src ? jbe short CopyUp ;V - yes, copy toward higher addresses cmp edi,eax ;U - dst < (src + count) ? jb CopyDown ;V - yes, copy toward lower addresses
-c
Image tools: ThumbNailer, Bobber, TIFFAssembler
-
the memcpy function has this little bit at the front:
; Check for overlapping buffers:
; If (dst <= src) Or (dst >= src + Count) Then
; Do normal (Upwards) Copy
; Else
; Do Downwards Copy to avoid propagation
mov eax,ecx ;V - eax = byte count...mov edx,ecx ;U - edx = byte count... add eax,esi ;V - eax = point past source end cmp edi,esi ;U - dst <= src ? jbe short CopyUp ;V - yes, copy toward higher addresses cmp edi,eax ;U - dst < (src + count) ? jb CopyDown ;V - yes, copy toward lower addresses
-c
Image tools: ThumbNailer, Bobber, TIFFAssembler
This protection seems to be implemented only in debug version, and I personally think is a major pain because it lets some easy to catch bugs to creep unobserved. I would expect release and debug versions to be consistent, not to have a different functionality :(
-
This protection seems to be implemented only in debug version, and I personally think is a major pain because it lets some easy to catch bugs to creep unobserved. I would expect release and debug versions to be consistent, not to have a different functionality :(
the MSDN does say that you shouldn't use memcpy for overlapping buffers. so, i don't think you can argue that it should work at all in such a situation. -c
Image tools: ThumbNailer, Bobber, TIFFAssembler
-
the MSDN does say that you shouldn't use memcpy for overlapping buffers. so, i don't think you can argue that it should work at all in such a situation. -c
Image tools: ThumbNailer, Bobber, TIFFAssembler
I perfectly agree - it is not supposed to work at all. I don’t understand why is working. Anyway, if you will take a look at the example in MSDN you'll see that the output is perfect ( compiled debug, I suppose ), even if the note says "MEMCPY.C: Illustrate overlapping copy: memmove, handles it correctly; memcpy does not" ;P