-5

I am trying to understand why this works:

char myst1r[] = "hello\n";
memmove(myst1r   , myst1r + 1 , 1 );//results in "eello"

while this one :

char *mystr = "hello\n";
memmove(mystr , mystr + 1 , 1 );

results in "Access violation writing location" error. Don't both myst1r and mystr point to the first member of char buffer? What do I miss here?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Michael IV
  • 11,016
  • 12
  • 92
  • 223
  • Please explain why you downvote? This is completely valid SO question. – Michael IV Sep 22 '13 at 13:27
  • 2
    @MichaelV It's a duplicate a lot of times, it has been overasked. Downvoters presumably have the feeling that you haven't dony any research before asking. Also, anybody with a minimal understanding of the difference between arrays and pointers (and especially string constants) wouldn't have had to ask this question. –  Sep 22 '13 at 13:35
  • It was asked in conjunction with char arrays which is indeed clear...In my case I was trying to work on char pointer. – Michael IV Sep 22 '13 at 13:36
  • 2
    _"Please explain why you downvote"_, put your mouse cursor on down arrow, that probably explains it – P0W Sep 22 '13 at 13:38
  • Please show me similar question?The one mentioned above DOESN"T deal with memmove.But whatever...I have understood what I needed from the answers.Some of you guys here are too tough.Even if this issue was answered indirectly in some other case does't mean such a question can't be valid.C/C++ noobs are also people. – Michael IV Sep 22 '13 at 13:40

2 Answers2

4

myst1r is an array of char that holds a copy of its initializer. mystr is a pointer to char that points to its initializer. In both cases, the initializer is a literal string. The difference is that you can modify the contents of an array, but you cannot modify the contents of a literal string.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • So does it mean I can't use memmove to modify char buffer pointer? – Michael IV Sep 22 '13 at 13:29
  • 1
    No, that's not what it means. What you can't do is **modify a string literal**. A string literal is a quoted string: `"hello\n"`, for example. If you have a pointer that points to modifiable text you can use `memmove`. – Pete Becker Sep 22 '13 at 13:33
  • Also the error code "access violation at writing location" makes sense because String literals are put in read only segments by compilers. – Aman Deep Gautam Sep 22 '13 at 13:33
  • @AmanDeepGautam - maybe, maybe not. The rule is that the behavior is undefined. On some systems it works just fine; on others it does not. – Pete Becker Sep 22 '13 at 13:34
  • @PeteBecker some time back I read it. May be this was the question:http://stackoverflow.com/questions/349025/is-a-string-literal-in-c-created-in-static-memory and the top voted answer says it – Aman Deep Gautam Sep 22 '13 at 13:37
  • 2
    @AmanDeepGautam - the first sentence of the top voted answer is "Where it's created is an implementation decision by the compiler writer, really." The language definition does **not** require that string literals be put in read-only memory, although that's quite common. – Pete Becker Sep 22 '13 at 13:39
2
h e l l o \0
0 1 2 3 4 5

The code

memmove(myst1r, myst1r + 1, 1 )

copies the character at place 1 (e) to place 0. Results in eello.

As for the second example

char *mystr = "hello\n";

mystr here is a string literal, modifying it leads to undefined behavior in both C and C++.

Just a little note, using memcpy to replace memmove will not work because the first two parameters overlap.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294