C++ 为什么我会得到;双重自由还是腐败;?
我正在尝试序列化结构,但程序因以下原因崩溃:C++ 为什么我会得到;双重自由还是腐败;?,c++,serialization,memory-leaks,runtime-error,C++,Serialization,Memory Leaks,Runtime Error,我正在尝试序列化结构,但程序因以下原因崩溃: *** glibc detected *** ./unserialization: double free or corruption (fasttop): 0x0000000000cf8010 *** #包括 #包括 #包括 结构虚拟 { std::字符串名; 双高; }; 模板 类序列化 { 公众: 静态无符号字符*toArray(T&T) { 无符号字符*缓冲区=新的无符号字符[sizeof(T)]; memcpy(缓冲区和t,大小f(t)
*** glibc detected *** ./unserialization: double free or corruption (fasttop): 0x0000000000cf8010 ***
#包括
#包括
#包括
结构虚拟
{
std::字符串名;
双高;
};
模板
类序列化
{
公众:
静态无符号字符*toArray(T&T)
{
无符号字符*缓冲区=新的无符号字符[sizeof(T)];
memcpy(缓冲区和t,大小f(t));
返回缓冲区;
};
静态T fromArray(无符号字符*缓冲区)
{
T;
memcpy(&t,buffer,sizeof(t));
返回t;
};
};
int main(int argc,字符**argv)
{
虚拟人;
human.name=“某人”;
人身高=11.333;
unsigned char*buffer=Serialization::toArray(人工);
Dummy Dummy=Serialization::fromArray(缓冲区);
std::cout我发现这个代码有两个问题:
通过memcpy
将包含std::string
的struct
调用未定义的行为。如果memcpy
调用的类不仅仅是纯结构(例如,std::string
),它可能会导致各种问题。在这种特殊情况下,我认为部分问题可能是std::string
有时会存储一个内部指针,指向包含字符串实际内容的字符缓冲区。如果memcpy
使用std::string
,则会绕过字符串的正常副本结构r这会复制字符串。相反,您现在有两个不同的std::string
实例共享一个指针,因此当它们被销毁时,它们都会尝试删除字符缓冲区,从而导致您看到的错误。除了不执行您正在执行的操作之外,没有简单的解决方法。这根本不安全。
您正在使用new[]
分配内存,但使用delete
删除它。您应该使用数组删除操作符delete[]
删除此内存,因为对其使用常规delete
将导致未定义的行为,可能导致此崩溃
希望这有帮助!您正在toArray
调用中复制字符串的内部缓冲区。使用fromArray
反序列化时,您在dummy
中“创建”第二个字符串,该字符串认为它拥有与human
相同的缓冲区,使用memcpy()
具有类型为std::string
的数据元素(或者实际上是任何非数据类型)。类将实际字符串数据存储在动态分配的缓冲区中。当您memcpy()时
std::string的内容
您可以通过将声明更改为:
struct Dummy
{
char name[100];
double height;
};
但是,这有固定大小的名称
缓冲区的缺点。如果要保持动态大小的名称
,则需要更复杂的toArray
和fromArray
实现,该实现不进行直接内存复制。std::string可能包含指向buf的指针包含字符串数据的fer。当您调用toArray(human)时,您正在memcpy()调用伪类的字符串,包括指向字符串数据的指针。然后,当您通过memcpy()创建新的伪对象时直接插入它,您创建了一个新的字符串对象,该对象与第一个对象具有相同的字符串数据指针。接下来,您知道,dummy被销毁,指针的副本被销毁,然后human被销毁,BAM,您获得了双重自由
一般来说,像这样使用MimcPy复制对象会导致各种各样的问题,比如你所看到的问题。它可能只是冰山的一角。相反,你可以考虑为要序列化的每个类显式地实现某种编组功能。
可选地,您可以查看C++的JSON库,它可以将事物序列化为一种方便的基于文本的格式。JSON协议通常用于自定义网络协议,其中要序列化对象以通过套接字发送。
基本上,他的<代码>序列化< /Cord>类需要一个< <代码> Enable(如果)。新的是可复制的
。使用std::vector
代替newt[]
。
struct Dummy
{
char name[100];
double height;
};