Reputation: 7583
I want to convert a set of values which are strings
, doubles
, and time_t
to a std::vector<unsigned char>
in C++. I am using memcpy
for that and calling it every time that I have a new value. I just realized that I have to call it backward to concatenate on the right order on my vector. After I convert all my values I want to convert back. The way I am doing is calling each time memcpy
again to get the original value converted back. But because the values after the first are in the middle of the vector I cannot convert it back properly.
How do I convert back all values from the vector separately? My code is below and the output too. Thanks
int main(void) {
std::string lat = "lat->";
double latitude = 13.123456;
std::vector<unsigned char> result(sizeof(lat) + sizeof(latitude));
std::cout << "copying to the vector" << std::endl;
memcpy(result.data(), &latitude, sizeof(latitude)); // add string to the vector
memcpy(result.data(), &lat, sizeof(result.size()) + sizeof(lat)); // add double to the same vector
std::cout << "copied to the vector\n" << std::endl;
std::cout << "printing the vector" << std::endl;
for (int j = 0; j < result.size(); j++) {
std::cout << result[j];
}
std::cout << std::endl;
std::cout << "printed the vector\n" << std::endl;
// testing converting back ...................
std::cout << "printing back the original value" << std::endl;
double d;
std::string value;
// make sure the vector is the right size
if (result.size() != (sizeof(d) + sizeof(lat)))
throw std::runtime_error {
"Size of data in vector and float do not match" };
// copy the bytes into the float
memcpy(&value, result.data(), sizeof(value));
std::cout << value;
memcpy(&d, result.data(), sizeof(value) + sizeof(d));
std::cout << d << std::endl;
std::cout << "printed back the original value\n" << std::endl;
}
Output:
copying to the vector
copied to the vector
printing the vector
��(�lat->Pş0��(�
printed the vector
printing back the original value
lat->6.95297e-310
printed back the original value
Segmentation fault (core dumped)
Upvotes: 0
Views: 2415
Reputation: 45444
As I said in the comments, don't do that sort of thing unless you know what you're doing (which you didn't).
Writing into the memory buffer:
std::string lat = "lat->";
double latitude = 13.123456;
std::vector<unsigned char> result(lat.length() + sizeof(latitude));
std::cout << "copying to the vector" << std::endl;
std::memcpy(result.data(), &latitude, sizeof(latitude)); // add double
std::memcpy(result.data()+sizeof(latitude), lat.data(), lat.size()); // add raw string data
std::cout << "copied to the vector\n" << std::endl;
Note that the destination pointer passed to memcpy
is different for the two calls, pointing each time to memory not previously used.
Care is required when reading back the string with memcpy
:
double d;
std::string value;
std::memcpy(&d, result.data(), sizeof(latitude)); // copy back the bytes of the double
value.resize(lat.length());
std::memcpy(value.data(),result.data()+sizeof(latitude), value.data(), lat.size());
You see that we need to know the number of characters (lat.size()
) before we can copy them from the buffer. This renders the whole approach questionable at best. I strongly recommend that, after understanding this example, you don't do this sort of thing anymore.
Upvotes: 2