1

I have a very simple c question regarding memcopy that I have been able to fix but not understand why. The following code crashes with an "access violation" at runtuime:

char *src = "HELLO WORLD!";
char * dest = "hello world!";
memcpy(dest, src, strlen(src)+1);

dest would appear to be big enough and as I understand it memcpy should just blindly copy the bytes so I don't understand the problem.

Changing dest to an array e.g char dest[13]; fixes things, so is it a requirement that dest must be uninitialized memory and creating an array does this for you whereas the pointer declaration does not?

Cheers

biffta
  • 189
  • 1
  • 6

3 Answers3

12

When you do:

char *dest = "hello world!";

"hello world!" is kept in the read-only parts of the memory and pointer named dest is pointed to it, making any writing operation on this memory illegal. So if you try to use it as a destination in your memcpy; it's an access violation.

You should use:

char dest[] = "hello world!";
Arjun Sreedharan
  • 11,003
  • 2
  • 26
  • 34
3

A string literal, "...", when used to initialise a char pointer, has type const char *, i.e. it's read-only.

dest should therefore have type const char *, at which point your code won't compile.

If you turn all your compiler warnings on then you'll get a warning for the "char * dest = ..." line.

user3392484
  • 1,929
  • 9
  • 9
  • "...." is `char[]` and it is read only because it resides in read only section. And `char* arr = malloc(6); const char* arrptr= arr; memcpy(arrptr,"hello",5); printf("%s",arrptr);` compiles without warnings at my machine – Dabo Mar 15 '14 at 16:40
  • char foo[] = "..." and char *foo = "..." aren't the same thing. Regarding compiler warnings: gcc 4.8 with default warning options says "passing argument 1 of memcpy discards const qualifier", which is precisely the problem. Either investigate turning on more warnings, or (if possible) get a better compiler. It's also worth compiling with multiple compilers, because they all spot different things. – user3392484 Mar 15 '14 at 16:56
  • Regarding const-ness of "...": C99 section 6.4.5, paras 5, 6: "The multibyte character sequence is then used to initialize an array ... If the program attempts to modify such an array, the behavior is undefined." – user3392484 Mar 15 '14 at 16:58
  • Regarding type of string literal read this answer http://stackoverflow.com/a/2245983/2549281 . – Dabo Mar 15 '14 at 17:04
  • Yes, but it's used in an initialiser, so you need also to read section 6.7.8 of the standard. In that char[] case you're initialising an array (para 14); in the char * case you're initialising a scalar (para 11). – user3392484 Mar 15 '14 at 17:07
1

char dest [] = "hello world!" and char* dest = "hello world!" is not the same thing. char dest[]="hello world!" is an array with 13 elements (the string is null-terminated). char* dest ="hello world!" is a pointer to an constant, null terminated string (also 13 characters).

Benedikt Bock
  • 1,007
  • 15
  • 37