How to copy a string to a unsigned char* on a struct?

Issue

a.h

struct loader_struct
{
    unsigned char* loader_x64;
};

extern loader_struct* g;

a.cpp

#include "a.h"

loader_struct g_startup;
loader_struct* g = &g_startup;

b.cpp

#include "a.h"

int _tmain(int argc, _TCHAR* argv[])
{
    std::string mdata = "abcdefg";
    g->loader_x64 = new unsigned char[mdata.length()];
    std::copy( mdata.begin(), mdata.end(), g->loader_x64 );
}

I’m trying to copy the content of mdata to loader_x64, its being copied, however, it contains some rubbish at the ending, what im doing wrong?

Solution

You are getting "rubbish" because whatever code is reading from loader_x64 is expecting it to be null-terminated, but you are not actually null-terminating it, so the reader reaches past the end of the buffer, which is undefined behavior.

You need to null-terminate the loader_x64 buffer, eg:

#include "a.h"

int _tmain(int argc, _TCHAR* argv[])
{
    std::string mdata = "abcdefg";
    g->loader_x64 = new unsigned char[mdata.length()+1];
    std::copy_n( mdata.c_str(), mdata.length()+1, g->loader_x64 );
    ...
    delete[] g->loader_x64;
}

Alternatively, you can simply set loader_x64 to point directly at mdata‘s internal data, which is guaranteed to be null-terminated since C++11, eg:

#include "a.h"

int _tmain(int argc, _TCHAR* argv[])
{
    std::string mdata = "abcdefg";
    g->loader_x64 = reinterpret_cast<unsigned char*>(mdata.data()); // C++17 and later
    or
    g->loader_x64 = reinterpret_cast<unsigned char*>(const_cast<char*>(mdata.c_str())); // prior to C++17
    ...
}

Answered By – Remy Lebeau

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published