Search code examples
cc++11c-stringsstrcpystrncpy

Value of char array changing, upon calling strcpy on a different char array


When experimenting ways to copy strings to a C style array, due to some weird limitations I stumbled upon this weird behavior, firstly trying to copy the string with std::string::copy() seems to work fine until I'm trying to copy the same string from another variable into another empty C style array with std::strcpy(), then the contents from the first array get some remaining content from the string.

#include <iostream>
#include <string>
#include <algorithm>
#include "string.h"

int main()
{
    std::string str = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";
    std::string str2 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";

    char cstr[64] = {0};
    char cstr2[64] = {0};

    str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));

    // cstr:  "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
    std::cout << "cstr:  \"" << cstr << "\"" << std::endl;

    strcpy(cstr2, str2.c_str());
    cstr2[sizeof(cstr2) / sizeof(cstr2[0]) - 1] = '\0';

    // cstr:  "m nonumy eirmod tempor invidunt ut l"
    std::cout << "cstr:  \"" << cstr << "\"" << std::endl;

    // cstr2: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
    std::cout << "cstr2: \"" << cstr2 << "\"" << std::endl;    
    return 0;
}

Surely I'm just missing some stupid cruicial point here.


Solution

  • In the first case

    str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));
    

    you limited the number of copied characters by the value of sizeof( cstr ) - 1.

    So the array cstr contains a string because it was zero-initialized.

    In the second case you did not limit the number of copied characters.

    strcpy(cstr2, str2.c_str());
    

    So the memory beyond the array cstr2 was overwritten because the string pointed to by str2.c_str() contains more characters than the size of the array cstr2.

    Instead you could write

    strncpy( cstr2, str2.c_str(), sizeof( cstr2 ) - 1 );
    

    using the function strncpy.