Search code examples
c++memcpywstring

Proper way to use memcpy for copying vector data to wstring


I have a raw data : 47 00 61 00 6D 00 65 00 41 00 73 00 73 00 65 00 74 00 = G.a.m.e.A.s.s.e.t. and it's stored at position 15 in a vector<char> array.

Now I want to copy it to a wstring value but I get '3221225477' error code.

Here's the code I wrote:

wstring                             string_Data;
std::memcpy(&string_Data, &file_buffer.data()[15], 18);

it's working on all of my other values , just wstring doesn't work.

If I use wcout << string_Data << endl; it doesn't crash but prints value with 3 of ? , It shows GameAsset??? in console.

And if I use wcout << string_Data.c_str() << endl; it will crash.

What am I doing wrong ? what is the proper way of doing this by using memcpy ???


Solution

  • std::wstring holds a pointer to character data that is stored elsewhere in memory. But you are not allocating that memory for it to point at, to copy your character data into. You are copying the character data directly onto the wstring itself, corrupting its internals, and likely surrounding memory.

    Try this instead:

    wstring string_Data;
    string_Data.resize(9);
    std::memcpy(&string_Data[0], file_buffer.data()+15, 18);
    // or:
    // std::copy(reinterpret_cast<wchar_t*>(file_buffer.data()+15), reinterpret_cast<wchar_t*>(file_buffer.data()+33), string_Data.begin());
    

    Alternatively, you can use the std::wstring::assign() method:

    wstring string_Data;
    string_Data.assign(reinterpret_cast<wchar_t*>(file_buffer.data()+15), 9);
    

    Or the std::wstring constructor:

    wstring string_Data(reinterpret_cast<wchar_t*>(file_buffer.data()+15), 9);
    

    Either way, just note that wchar_t is not very portable. It is 16bit only on Windows, where wchar_t is handled using UTF-16. If you need this code to work on other platforms, where wchar_t is handled using UTF-32 instead, then you should interpret the vector data using char16_t and copy it into astd::u16string, or convert it to std::wstring using std::wstring_convert or any Unicode library of your choosing (ICU, etc).