2

According to C11 N1570 standard draft:

7.24.2.2 "The memmove function":

The memmove function copies n characters from the object pointed to by s2 into the object pointed to by s1. Copying takes place as if the n characters from the object pointed to by s2 are first copied into a temporary array of n characters that does not overlap the objects pointed to by s1 and s2, and then the n characters from the temporary array are copied into the object pointed to by s1

So if I choose to move a buffer of size 32K using (file_size = 32K)

memmove(io_Buffer, io_Buffer+17, file_size);

won't the temp buffer be of size 32K?

Question

Can the program allocate dynamic memory on its own? Does it allocate and free the memory in that one line?

clamentjohn
  • 3,417
  • 2
  • 18
  • 42
  • 1
    Try [`ltrace`](https://unix.stackexchange.com/a/462710/32558), read glibc source, read GCC source, step debug the assembly, and pray that it does not go too deep :-) – Ciro Santilli OurBigBook.com Mar 28 '19 at 10:52
  • 1
    @CiroSantilli新疆改造中心六四事件法轮功 This was for an embedded application (and.. that's why I was too concerned about the memory), but will try out `ltrace` for sure. – clamentjohn Mar 28 '19 at 11:45

2 Answers2

7

I think you missed the "as if" in that sentence. That means the effects will be the same as if it did that, not that it will actually do that. I've never seen an implementation of memmove that actually uses a temporary array.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    Thank you. Found [this](https://stackoverflow.com/questions/13339582/why-is-linux-memmove-implemented-the-way-it-is) other question which points to a few implementations. Also, cheers on Ripple! – clamentjohn Mar 27 '19 at 05:20
1

The memmove is not a single implementation in modern compilers; it is considered an intrinsic instead. It is easiest to show with an example how the "as if" works:

#include <string.h>

void test_memmove(void * restrict dst, const void * restrict src, size_t n) {
    memmove(dst, src, n);
}

the restrict in parameters tell that the memory accessed through the pointers do not overlap. So GCC knows to compile this to

test_memmove:
        jmp     memcpy

Because the compiler was able to take the restrict into account and "prove" that the memory areas pointed to by these 2 do not overlap, the call to memmove was immediately changed to a (tail) call to memcpy!