Search code examples
c++castingreinterpret-cast

serialize and deserialize datas with reinterpret_cast


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 ?


Solution

  • 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.

    Read What is stack unwinding?

    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*