strcpy in C++

Hello,

I have two strings and used strcpy.
After strcpy I expected s1 will be: abcdefgh and s2: abcde but I have: (please see photo)
https://ibb.co/zXtKxR6

It's weird!


1
2
3
4
    char s1[] = "abcdefgh";
    char s2[] = "ijkl";

    strcpy(s2, s1);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// StringCopy.cpp

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
     char s1[] = "abcdefgh";
     char s2[] = "ijkl";
     cout << s1 << endl;
     cout << s2 << endl;

     strcpy(s2, s1);

     cout << s1 << endl;
     cout << s2 << endl;

     return 0;
}

// C:\Users\mark_>cd C:\Users\mark_\myCppprograms
// C:\Users\mark_\myCppprograms>c++ StringCopy.cpp -o StringCopy.exe
// C:\Users\mark_\myCppprograms>StringCopy
// abcdefgh
// ijkl
// abcdefgh
// abcdefgh 

Last edited on
I copy your code and run it. my result is:

abcdefgh
ijkl
fgh
abcdefgh
Could you post all of your code? If I press "Edit & Run" in my post it returns the same results I obtained on my own computer and provided in my post.
It's weird!

Not really. You're overflowing the bounds of the array, so you are overwriting s1 and leaving s2 unterminated (look closely at your picture notice s2 is missing the end of string character.

The destination array must be large enough to hold the desired string along with the end of string character.



closed account (z05DSL3A)
The behavior is undefined if the dest array is not large enough. The behavior is undefined if the strings overlap.
-- https://en.cppreference.com/w/c/string/byte/strcpy
When defining an array, if you don't give the size then the size is determined from the size of the initializer. E.g.,

1
2
3
4
5
6
7
8
int a[] = {1, 2, 3, 4};   // This array is 4 elements long.
                          // The contents are 1, 2, 3, 4

int b[4] = {1, 2};        // This array is also 4 elements long.
                          // The contents would be 1, 2, 0, 0.

int c[4];                 // This array is also 4 elements long.
                          // The contents are indeterminate. 

You can use a string literal to initialize a char array. A string literal is one char longer than the chars between the quotes since a null char '\0' is added to the end. So "hello" is 6 chars long.

So with your arrays, s1 is 9 chars long and s2 is 5 chars long. You are trying to copy the contents of s1 to s2, but s2 is not long enough to hold the chars. Therefore the chars get written past the end of s2. In your screenshot we see that on your system the contents of s1 are stored directly after s2, so the chars that overflow s2 are written into the beggining of s1.

IcterusGalbula's result is different from yours because he is on a different system (linux vs windows, for example, or even just a different compiler on the same system). You could both print the addresses of your variables to see what order they are stored in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
     char s1[] = "abcdefgh";
     char s2[] = "ijkl";

     cout << "s1: " << &s1 << "\ns2: " << &s2 << '\n';

     cout << s1 << '\n' << s2 << '\n';

     strcpy(s2, s1);

     cout << s1 << '\n' << s2 << '\n';
}

My output shows that s1 is after s2 in memory for me:

s1: 0x7ffcdf6fa8e3
s2: 0x7ffcdf6fa8de
abcdefgh
ijkl
fgh
abcdefgh


The upshot of this is to ensure that the char array you are copying to has enough room to hold the chars. To fix your code you could explicitly size the arrays so that s2 is at least long enough to hold the contents of s1.

1
2
char s1[50] = "abcdefgh";
char s2[50] = "ijkl";

Last edited on
Topic archived. No new replies allowed.