I am trying to serialize a struct, but the program crashed with:
*** glibc detected *** ./unserialization: double free or corruption (fasttop): 0x0000000000cf8010 ***
#include <iostream>
#include <cstdlib>
#include <cstring>
struct Dummy
{
std::string name;
double height;
};
template<typename T>
class Serialization
{
public:
static unsigned char* toArray (T & t)
{
unsigned char *buffer = new unsigned char [ sizeof (T) ];
memcpy ( buffer , &t , sizeof (T) );
return buffer;
};
static T fromArray ( unsigned char *buffer )
{
T t;
memcpy ( &t , buffer , sizeof (T) );
return t;
};
};
int main ( int argc , char **argv )
{
Dummy human;
human.name = "Someone";
human.height = 11.333;
unsigned char *buffer = Serialization<Dummy>::toArray (human);
Dummy dummy = Serialization<Dummy>::fromArray (buffer);
std::cout << "Name:" << dummy.name << "\n" << "Height:" << dummy.height << std::endl;
delete buffer;
return 0;
}
I see two problems with this code:
You are invoking undefined behavior by
memcpying astructcontaining astd::stringinto another location. If youmemcpya class that isn’t just a pure struct (for example, astd::string), it can cause all sorts of problems. In this particular case, I think that part of the problem might be thatstd::stringsometimes stores an internal pointer to a buffer of characters containing the actual contents of the string. If youmemcpythestd::string, you bypass the string’s normal copy constructor that would duplicate the string. Instead, you now have two different instances ofstd::stringsharing a pointer, so when they are destroyed they will both try to delete the character buffer, causing the bug you’re seeing. There is no easy fix for this other than to not do what you’re doing. It’s just fundamentally unsafe.You are allocating memory with
new[], but deleting it withdelete. You should use the array deleting operatordelete[]to delete this memory, since using regulardeleteon it will result in undefined behavior, potentially causing this crash.Hope this helps!