10

The second arg in the prototypes for memmove/memcpy/strcpy are similar: For example:

void *memmove(void *dest, const void *src, size_t n); //const void*
char *strcpy(char *dest, const char *src); //const char*

But apparently, if dest and src overlap, then src's content will be altered, violating the const void/char *?

Alcott
  • 17,905
  • 32
  • 116
  • 173

4 Answers4

20

const void* means that the referand will not be modified through that pointer.

If there are other, non-const pointers to the same object (also known as "aliasing"), then of course it can still be modified through those. In the scenario you describe, that other pointer is dest.

By the way, in the case of strcpy, behavior is undefined if the regions overlap, and in C99 the signature is char *strcpy(char * restrict s1, const char * restrict s2);. But for memmove, aliasing is OK. By giving it overlapping regions you've given it "permission" to modify the dest region, and it will do that.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • do you mean, if I cannot make sure whether dest and src overlap or not, I'd better not use strcpy, right? – Alcott Sep 16 '11 at 13:32
  • 1
    @Alcott: that's right. What you'll most likely see in practice is that if your regions overlap with `dest < src` then it'll work. If they overlap with `src < dest` then the nul byte at the end of `src` will be overwritten before it's read, and then the function will go into an infinite loop trashing memory until something terminal happens. But you can't rely on either of those behaviors. – Steve Jessop Sep 16 '11 at 13:35
7

The argument is marked const void * to indicate memmove will never modify the memory pointed to by src using that pointer. If overlap occurs the memory is modified using the dest pointer, not the src pointer, so the guarantee is not violated.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
4

It means memmove guarantees it won't directly modify the memory pointed by src.

Of course if the two blocks overlap memmove will change the so-called "const" memory. const is ca contract attached to a name. There's no way to make the actual memory read-only.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
4

As above memove will not modify the contents of memory through the "src" pointer but will through the "dest" pointer.

The const refers to how the pointers are used, it does not add any memory protection.

If both pointers to point to an overlapping region of memory then anything could happen as it's not defined if the copy will start from the "src" and increment or start from "src + n" and decrement.

John Beckett
  • 126
  • 2
  • sorry for looking like a repeat answer by I posted at the same time the above was edited – John Beckett Sep 16 '11 at 13:37
  • that kind of thing happens all the time, it's not a problem. There are usually subtle differences in the answers even when they're substantially the same, and often it's quite useful to have several explanations of the same thing -- one reader will understand one of them best, someone else will understand another. – Steve Jessop Sep 16 '11 at 14:08