Can anyone explain what's wrong with my code
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
int main () {
char x[] = "abcdefghi123456"; // length 15
cout << "original string length: " << strlen(x) << endl;
cout << "string before modified: " << x << endl;
while ((strlen(x) % 4) != 0)
{
memcpy(x strlen(x),"n",1);
}
cout << "string length after modified: " << strlen(x) << endl;
cout << "string after modified: " << x << endl;
return 0;
}
The result of the code above is:
CodePudding user response:
First off, <cstring>
and <string.h>
are the same thing, just that <cstring>
wraps the contents of <string.h>
into the std
namespace. There is no need to use both headers, use one or the other - use <string.h>
in C, and <cstring>
in C .
More importantly, x
is a fixed-sized array of 16 char
s, as it is being initialized with a string literal containing 15 alpha-numerics a null terminator. This is the same as if you had done the following instead:
//char x[] = "abcdefghi123456";
char x[] = {'a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','\0'};
Thus, the initial strlen(x)
returns 15 (because the null terminator is not counted). 15 % 4
is not 0, so the while
loop is entered, and on its very 1st iteration, x strlen(x)
points to the array's '\0'
null terminator:
{'a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','\0'}
^ ^
| |
x x 15
Which memcpy()
then overwrites with 'n'
:
{'a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','n'};
^
From that point on, x
is no longer null-terminated, so any further uses of strlen(x)
will cause undefined behavior due to it reaching beyond the bounds of the array into surrounding memory.
For what you are trying to do, use std::string
instead:
#include <iostream>
#include <string>
using namespace std;
int main () {
string x = "abcdefghi123456"; // length 15
cout << "original string length: " << x.size() << endl;
cout << "string before modified: " << x << endl;
while ((x.size() % 4) != 0)
{
x = 'n';
}
/* alternatively:
x.resize((x.size() 3) & ~3, 'n');
*/
cout << "string length after modified: " << x.size() << endl;
cout << "string after modified: " << x << endl;
return 0;
}