0

Here in this sample program to illustrate this behavior of strcpy(),I wrote a string "S" into a bigger string previous which original had "Delaware".But this overwriting only affects the first two characters in the original string.The rest of the original string continue to have the same values.How to deal with this? (Even memcpy() seems likely to have the same behavior).I mean, how to turn the remaining characters into 0?Or the rest of the characters in the string retaining their original values has no side-effects?

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

int main()
{
    char previous[10]="Delaware";
    printf("The character at position 4 is %c\n",previous[4]);
    strcpy(previous,"S");
    printf("The character at position 4 later is %c",previous[4]);
}
Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
  • why do you want to change the rest of the string to 0? – yngccc May 11 '13 at 03:31
  • Why would it do that by default? It's a string function and strings aren't concerned with what's after the null terminator anyway, so it's just a waste of cycles most of the time. – chris May 11 '13 at 03:31
  • `strcpy` will also copy the null terminator so if you do a `printf( "%s\n", previous) ;` it will only print `S`, this assumes the destination is large enough to also hold the null terminator. – Shafik Yaghmour May 11 '13 at 03:31
  • string functions guarantee that the result is a valid string if your source was a valid string. memcpy, however, not being a string function, has no such guarantee – xaxxon May 11 '13 at 04:29

5 Answers5

4

The strcpy function does this:

previous                 "S"
     |                    |
     v                    v
 -- -- -- -- -- -- -- -- -- --   -- -
| D| e| l| a| w| a| r| e|\0| |  | S|\0|
 -- -- -- -- -- -- -- -- -- --   -- --
  ^  ^                            |  |
  |  |                            |  |
  |   - - - - - - - - - - - - - - - -
  |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|

leaving your memory looking like this:

 -- -- -- -- -- -- -- -- -- --   -- -
| S|\0| l| a| w| a| r| e|\0| |  | S|\0|
 -- -- -- -- -- -- -- -- -- --   -- --

The extra characters after the 0 will not matter when referring to previous in things like printf. Just like the extra memory location after the 0 in Delaware didn't affect your using previous when referencing it.

HalR
  • 11,411
  • 5
  • 48
  • 80
  • @HaIR Doesn't `strcpy()` get ride of the `|S|\0|` on the right after it has copied it over `De` part of `Delaware`? Shouldn't a respected library function like `strcpy()` empty that memory of `|S|0|` once it's use is over? – Rüppell's Vulture May 11 '13 at 15:18
  • Nope it does not. It doesn't do anything to that memory. It is strcpy, not strcpyandfree or strcpyandclear (those don't exist, as far as I know) – HalR May 11 '13 at 15:32
1

strcpy will also copy over the null terminator so if you do a:

printf( "%s\n", previous) ;

in your case you will only see S which in most situations is sufficient. If you really want to zero out the memory before you do a strcpy you can always use memset before the copy:

memset(previous, 0, sizeof(previous)) ;
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
0

1) This is correct behaviour for strcpy(). If you use str* values to access the string, you'll never see any of the unchanged bytes, as a string terminator ('\0') was placed at the second position (index 0) and str* functions won't pass end of string.

2) It's NOT the behaviour of memcpy(). If you memcpy(str2, str1, 10), 10 characters will be copied. memcpy(previous, "S", 10) isn't a good idea, however ;-)

3) If you want to zero previous[] before the strcpy(), try something like memset(previous, '\0', sizeof(previous))

Arlie Stephens
  • 1,146
  • 6
  • 20
0

Are you implementing your own strcpy() function? If so, don't forget to copy the null terminator from the source string into the destination. The null terminator is what tells C where the String ends. The default implementation in the string library does this, and when you print it out using printf() it will display what you expect.

If memory allocation is a concern then you could free() the space taken by the previous string and then malloc() enough for the string you are copying, but this is overkill in most situations unless you really are worrying about memory constraints, in which case you probably wouldn't use the string library.

Aaron D
  • 7,540
  • 3
  • 44
  • 48
0

The rest of the characters in the string really should have no effect, as the previous string will have S as as the first character (i.e. previous[0]) and a NULL value as the second. Unless your code examines specific characters in the string, then it shouldn't matter. However, if you really want the string to have the value you copied and then all NULLs, you can clear the string before doing the strcpy.

memset(previous, 0, sizeof(previous));
strcpy(previous, "S");
mtwaddell
  • 189
  • 4