Home > front end >  <ask> modified string using memcpy
<ask> modified string using memcpy

Time:12-23

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:

image

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 chars, 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;
}
  •  Tags:  
  • c
  • Related