使用 reinterpret_cast 序列化和反序列化数据
serialize and deserialize datas with reinterpret_cast
我尝试做一些简单的事情:我有 2 个函数,第一个生成 2 个 char 数组和 1 个 int,然后将它们连接起来,reinterpret_cast 作为 void*
和 returns 它。
第二个 reinterpret_cast 它作为 char*
打印出来。
问题是:如果我 reinterpret_cast 它作为 char*
并在 void*
转换之后打印它(在同一个函数中),它运行良好,但在反序列化函数中却不行。
这是我的代码:
#include <sstream>
#include <unistd.h>
void * serialize( void )
{
char s1[9];
char s2[9];
int n;
std::string alphanum = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
s1[8] = '[=11=]';
s2[8] = '[=11=]';
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;
}
我的输出如下:
s1: 6dfhkmoq
n: 1857
s2: tyADFHKM
6dfhkmoq1857tyADFHKM
6�c2X� d2X�
我怎样才能得到相同的输出?
那是因为您正在 return 指向 string
对象(具有自动存储)的内存。来自 cppeference
Return value
Pointer to the underlying character storage.
当堆栈展开时,为字符串分配的内存被覆盖(它的内部缓冲区也是如此)。当块由于异常或到达控制流结束时结束时,就会发生这种情况。
阅读What is stack unwinding?
为确保您的内存位置仍然有效,您必须在堆上分配它。您可以改为创建 shared_ptr 和 return。
但是很多时候 reinterpret_cast
闻起来像糟糕的设计,因此您可能需要重新考虑为什么要将类型隐藏在 void*
后面
我尝试做一些简单的事情:我有 2 个函数,第一个生成 2 个 char 数组和 1 个 int,然后将它们连接起来,reinterpret_cast 作为 void*
和 returns 它。
第二个 reinterpret_cast 它作为 char*
打印出来。
问题是:如果我 reinterpret_cast 它作为 char*
并在 void*
转换之后打印它(在同一个函数中),它运行良好,但在反序列化函数中却不行。
这是我的代码:
#include <sstream>
#include <unistd.h>
void * serialize( void )
{
char s1[9];
char s2[9];
int n;
std::string alphanum = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
s1[8] = '[=11=]';
s2[8] = '[=11=]';
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;
}
我的输出如下:
s1: 6dfhkmoq
n: 1857
s2: tyADFHKM
6dfhkmoq1857tyADFHKM
6�c2X� d2X�
我怎样才能得到相同的输出?
那是因为您正在 return 指向 string
对象(具有自动存储)的内存。来自 cppeference
Return value
Pointer to the underlying character storage.
当堆栈展开时,为字符串分配的内存被覆盖(它的内部缓冲区也是如此)。当块由于异常或到达控制流结束时结束时,就会发生这种情况。
阅读What is stack unwinding?
为确保您的内存位置仍然有效,您必须在堆上分配它。您可以改为创建 shared_ptr 和 return。
但是很多时候 reinterpret_cast
闻起来像糟糕的设计,因此您可能需要重新考虑为什么要将类型隐藏在 void*