I try to make something simple: I have 2 functions, the first generates 2 char arrays and 1 int then concat them, reinterpret_cast as a void*
and returns it.
The second one reinterpret_cast it as a char*
and print it.
The problem is: if I reinterpret_cast it as a char*
and print it just after the void*
cast (in the same function), it works well, but not in the deserialize function.
Here is my code :
#include <sstream>
#include <unistd.h>
void * serialize( void )
{
char s1[9];
char s2[9];
int n;
std::string alphanum = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
s1[8] = '\0';
s2[8] = '\0';
for (int i = 0; i < 8; i++)
{
usleep(1);
s1[i] = alphanum[clock() % (alphanum.length() - 1)];
}
n = clock() % 2147483647;
for (int i = 0; i < 8; i++)
{
usleep(1);
s2[i] = alphanum[clock() % (alphanum.length() - 1)];
}
std::cout << "s1: " << s1 << std::endl;
std::cout << "n: " << n << std::endl;
std::cout << "s2: " << s2 << std::endl;
std::stringstream ss;
std::string str;
ss << s1 << n << s2;
ss >> str;
char * c = const_cast<char*>(str.c_str());
void * d = reinterpret_cast<void*>(c);
std::cout << reinterpret_cast<char*>(d) << std::endl; // HERE IT WORKS
return d;
}
void deserialize( void * raw )
{
char* c = reinterpret_cast<char*>(raw);
std::cout << c << std::endl; //HERE IT DOESN'T WORK
}
int main(void)
{
void* serialized = serialize();
deserialize(serialized);
return 0;
}
my output looks like:
s1: 6dfhkmoq
n: 1857
s2: tyADFHKM
6dfhkmoq1857tyADFHKM
6�c2X� d2X�
How can I do to have the same output ?
That's because you are returning a pointer to memory of a string
object(with automatic storage). From cppeference
Return value
Pointer to the underlying character storage.
The memory allocated for the string gets overwritten (and so does its internal buffer) when the stack unwinds. That happens when the block ends either due to an exception or when reaching the end of control flow.
To make sure that your memory location is still valid you will have to allocate it on the heap. You can create a shared_ptr and return that instead.
However very often reinterpret_cast
smells like bad design so you may want to reconsider why do you want to hide the type behind a void*