tags:

views:

126

answers:

5

Hi all,

consider the following code:

t[7] = "Hellow\0";
s[3] = "Dad";
//now copy t to s using the following strcpy function:

void strcpy(char *s, char *t) {
    int i = 0;

    while ((s[i] = t[i]) != '\0')
        i++;
}

the above code is taken from "The C programming Language book". my question is - we are copying 7 bytes to what was declared as 3 bytes. how do I know that after copying, other data that was after s[] in the memory wasn't deleted?

and one more question please: char *s is identical to char* s?

Thank you !

+2  A: 

About the first question.

If you're lucky your program will crash.

If you are not it will keep on running and overwrite memory areas that shouldn't be touched (as you don't know what's actually in there). This would be a hell to debug...

About the second question.

Both char* s and char *s do the same thing. It's just a matter of style.

That is, char* s could be interpreted as "s is of type char pointer" while char *s could be interpreted as "s is a pointer to a char". But really, syntactically it's the same.

klez
Except for local variable declarations, where "char* a, b;" has unexpected results.
wj32
of course :-)))
klez
+1  A: 

As you correctly point out, passing s[3] as the first argument is going to overwrite some memory that could well be used by something else. At best your program will crash right there and then; at worst, it will carry on running, damaged, and eventually end up corrupting something it was supposed to handle.

The intended way to do this in C is to never pass an array shorter than required.

By the way, it looks like you've swapped s and t; what was meant was probably this:

void strcpy(char *t, char *s) {
    int i = 0;

    while ((t[i] = s[i]) != '\0')
        i++;
}

You can now copy s[4] into t[7] using this amended strcpy routine:

char t[] = "Hellow";
char s[] = "Dad";

strcpy(t, s);

(edit: the length of s is now fixed)

romkyns
Explicitly specifying the terminating `'\0'` leaves you with one more character than will fit in each buffer, as C strings are always automatically null-terminated.
Jon Purdy
@Jon thanks - fixed.
romkyns
+1  A: 

That example does nothing, you're not invoking strcpy yet. But if you did this:

strcpy(s,t);

It would be wrong in several ways:

  • The string s is not null terminated. In C the only way strcpy can know where a string ends is by finding the '\0'. The function may think that s is infinite and it might corrupt your memory and make the program crash.
  • Even if was null terminated, as you said the size of s is only 3. Because of the same cause, strcpy would write memory beyond where s ends, with maybe catastrophic results.

The workaround for this in C is the function strncpy(dst, src, max) in which you specify the maximum number of chars to copy. Still beware that this function might generate a not null terminated string if src is shorter than max chars.

LatinSuD
Regarding bullet #1: He is copying from `t` _to_ `s` so it doesn't matter if `s` is a ntbs or not. All it needs is a null terminator for `t` which is there.
dirkgently
+1  A: 

I will assume that both s and t (above the function definition) are arrays of char.

how do I know that after copying, other data that was after s[] in the memory wasn't deleted?

No, this is worse, you are invoking undefined behavior and we know this because the standard says so. All you are allowed to do after the three elements in s is compare. Assignment is a strict no-no. Advance further, and you're not even allowed to compare.

and one more question please: char s is identical to char s?

In most cases it is a matter of style where you stick your asterix except if you are going to declare/define more than one, in which case you need to stick one to every variable you are going to name (as a pointer).

dirkgently
thanks everyone for the answers.
rob
A: 

a string-literal "Hellow\0" is equal to "Hellow"

if you define

t[7] = "Hellow";
s[7] = "Dad";

your example is defined and crashes not.

A string-literal "Foo" will have an internal representation {'F','o','o','\0'} but that's not the question anyway...
Cedric H.