cstringsubstringvalgrindmemmove

Using memmove for overlapping strings


I was writing a program where I had to copy two overlapping strings one into another. After looking around, memmove seemed like what I needed for the task. However, it doesn't seem to be working the way it seemed to me it did from reading the man pages.

I've written the following code for testing:

#include <stdio.h>
#include <string.h>

int main () {

  char* s = "foobar"; // 7 bytes
  memmove(s, s+1, 6);
  printf("%s\n", s);

  return 0;
}

I expected that oobar should be printed, however, I got a segmentation fault at execution. Same goes if I specify less than 6 for the 3rd parameter. Running through valgrind, it says

==36627==  Bad permissions for mapped region at address 0x10A004
==36627==    at 0x4852A13: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==36627==    by 0x10917B: main (in /home/[..]/tmp)

This is the second time I've used valgrind in my life so I can't really tell what it's saying beyond the fact that memmove is the cause behind the seg fault.

What did I do wrong here?


Solution

  • You're attempting to modify a string literal which isn't allowed. Such strings are read-only, and in fact typically reside in a read-only section of memory. This is what the message "Bad permissions for mapped region" is telling you.

    Change s from a pointer to a string literal to an array, and make sure you leave room for the moved string:

    char s[10] = "foobar";