Question

Take the following program:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    char a[8] = "Hello, ";
    char b[7] = "world!";

    strcat(a, b);

    cout << a;

    return 0;
}

Notice that a and b have the same size as their assigned strings.

The documentation states that for strcat(a, b) to work, a needs to be large enough to contain the concatenated resulting string.

Nevertheless, cout << a displays "Hello, world!". Am I entering undefined behavior?

Was it helpful?

Solution

"Am I entering undefined behavior?"

Yes. A region at the end of a[] has been written over. It worked, this time, but might have belonged to something else.

Here I use a struct to control memory layout, and demonstrate it:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    struct S {
        char a[8];
        char b[5];
        char c[7];
    };

    S s;
    strcpy( s.a , "Hello, " );
    strcpy( s.b , "Foo!" );
    strcpy( s.c , "world!" );


    strcat(s.a, s.c);

    cout << s.a << endl;
    cout << s.b << endl;

    cin.get();

    return 0;
}

This outputs:

Hello, world!
orld!

Instead of:

Hello, world!
Foo!

The strcat() has stomped all over b[].

Please note that in a real life example such bugs may be far more subtle, and lead you to wondering why perfectly innocent function calls 250 lines later crash and burn horribly. ;-)

EDIT: May I also recommend that you use strcat_s, instead? Or, even better, std::strings:

#include <string>
#include <iostream>

using namespace std;

int main()
{
    string a = "Hello, ";
    string b = "world!";
    a = a + b;
    cout << a;
}

OTHER TIPS

Am I entering undefined behavior?

Yes.


If the documentation says "a needs to be large enough to contain the concatenated resulting string", why don't you simply believe it? What is there to doubt?

In your program, array a is not large enough to contain the result. Therefore, your code is wrong and should be fixed. In the words of the standard, you are indeed entering undefined behavior, which means it may work or it may not...

strcat does what is says on the tin viz. copies b onto the end of a without any care as to what data is already there. Since both variables are on the stack one after the other things work. But try

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    char a[8] = "Hello, ";
    int i =  10;
    char b[7] = "world!";

    strcat(a, b);

    cout << a << i;

return 0;
}

And you will probably get an unexpected result since your stack has been corrupted by strcat

That is correct.... The behavior is undefined. Just because you got that answer does not mean that it will not crash next time since the array a is too small.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top