0

In Zlib algorithm we have decoding function. This function called inflate. At the end of the function we need to copy bytes to output. Example: (full code)

  if (copy > left) copy = left;
        left -= copy;
        state->length -= copy;
        do {
            *put++ = *from++;
        } while (--copy);
        if (state->length == 0) state->mode = LEN;
        break;
    case LIT:
        if (left == 0) goto inf_leave;

In this example we have do while loop with copying bytes by incrementing pointers. So we have "copy" iterations. I have question: why we cannot use just memcpy(put, from, copy) (and increment pointers after that) instead loop? Why we will have wrong decoding results in some case (when we encoding by 8kb blocks) ?

About wrong results: in result of decoding we can have unitialized bytes (little bit) . As if memcpy copy some bytes from non initialized memory.

  • *"Why we will have wrong decoding results in some case (when we encoding by 8kb blocks) ?"* What wrong results? Please include necessary information in the question. – user694733 Mar 13 '18 at 11:30
  • Yes, that would be posible. But don't underestimate the speed of an optimized, tight loop! – Paul Ogilvie Mar 13 '18 at 11:30
  • I suppose that's to be independent of `memcpy` function. But I doubt that it's faster than `memcpy`. – Jean-François Fabre Mar 13 '18 at 11:34
  • I think it is some features of this algorithm, but I don't know what feature. –  Mar 13 '18 at 11:41
  • Show the exact code that you use when you're calling memcpy. – Mike Andrews Mar 13 '18 at 12:16
  • Mike, just remove loop and write memcpy(put, from, copy); put+=copy; from+=copy ; copy=0; –  Mar 13 '18 at 12:36
  • `memcpy` doesn't allow overlapping memory ranges, this loop does. The correct comparison is [`memmove`](https://stackoverflow.com/questions/1201319/what-is-the-difference-between-memmove-and-memcpy). Of course, it's possible that `memcpy` would work here; there's insufficient context to determine if the ranges can overlap. – MSalters Mar 13 '18 at 12:40

1 Answers1

2

I could not use memcpy(), nor could I use memmove(). The reason is that the copies are often overlapped, with the intent being to copy just-copied bytes. The behavior of memcpy() for overlapped source and destination blocks is undefined. The behavior of memmove() in that case it quite defined, but exactly the opposite of what is needed, where memmove() avoids copying just-copied data.

I have no idea what you did that gave wrong results, but the copy that is there never copies from uninitialized memory.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Thank you, problems was with overlapped memory blocks. About wrong results: i tried to copy more than 1 bytes by memcpy, but at the start i did not know, why it did not works. Now i fixed it. –  Mar 15 '18 at 09:29