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;
    };