What happened to the "N"?

I'm working my way through Learn C++ in 1 hour a day.

In chapter 4, exercise 7 I had a small typo. I fixed it easily enough, but I'm somewhat mystified at the results.

Here's the correct listing, and the output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
james@independence:~/c++/ch4$ cat 4.7.cpp
// Listing 4.7 using strcopy()

#include <iostream>
#include <string.h>
using namespace std;

int main()
{
        char String1[] = "No man is an island";
        char String2[80] = {'\0'};

        strcpy(String2,String1);

        cout << "String1: " << String1 << endl;
        cout << "String2: " << String2 << endl;
        return 0;
}
james@independence:~/c++/ch4$ ./4.7
String1: No man is an island
String2: No man is an island


OK, so far so good. Now here's the typo version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
james@independence:~/c++/ch4$ cat 4.7.a.cpp
// Listing 4.7 using strcopy()

#include <iostream>
#include <string.h>
using namespace std;

int main()
{
        char String1[] = "No man is an island";
        char String2[] = {'\0'};

        strcpy(String2,String1);

        cout << "String1: " << String1 << endl;
        cout << "String2: " << String2 << endl;
        return 0;
}
james@independence:~/c++/ch4$ g++ -o 4.7.a 4.7.a.cpp
james@independence:~/c++/ch4$ ./4.7.a
String1: o man is an island
String2: No man is an island


Bizzare. I can see where I left the number of characters out when I initialized String2. So I am guessing it would have made a one character string with the null character. But String1 is identical in both versions, and String1 is the SOURCE, not the destination for strcpy in any case.

Why would strcpy strip off the leading N on String1 in the typo example?
It's got something to do with the initialization of String2. I don't exactly know why this has happened but I think this is some sort of buffer overflow because you are copying String1 which is larger than String2 into String2.
Hmm. So the tail end of String2 is somehow erasing the first character of String1?

It seems strange to me, as after String1 is initialized the only thing that happens to it is being read as the source for String2.

I wish I could step through the code line by line and see what happens to String1 in every step.
It is as mcleano says... at that point String2 is an array of 1 character. String2 is on the stack, so String1 is essentially being copied into free stack space. Stack gets used by the compiler internally and to push parameters for function calls such as strcpy, and ostream's operator<<( const char* ) and endl, etc.

Essentially the behavior is undefined so it's really not worth the effort trying to figure out exactly how that is happening. The bottom line is that it will behave differently on different OSes, different compilers, different versions of the same compiler, different compile-time options, etc.
Topic archived. No new replies allowed.