std::vector memory manipulation with serialization and deserialization This is my code and I would like to get it code reviewed. It is functional and behaves as expected.

I pass some basic types to the Serialize() function and then deserialize the output to get back the original value.

size_t returnSize(const char* s)
{
       string string(s);
       return string.size();
};
template&lt;typename T&gt;
size_t returnSize(const T&amp; t)
{
       return sizeof(t);
};

template&lt;typename T&gt;
string Serialize(const T&amp; t)
{
    T* pt = new T(t);
    vector&lt;char&gt; CasttoChar;

    for (int i =0 ;i&lt;returnSize(t);i++)
    {
        CasttoChar.push_back(reinterpret_cast&lt;const char*&gt;(pt)[i]);
    }
    delete pt;
    return  string( CasttoChar.begin(), CasttoChar.end() );

};

template&lt;&gt;
string Serialize&lt;string&gt;(const string&amp; t)
{
    return Serialize(t.c_str()); 
};

template&lt;typename T&gt;
T DeSerialize(const string&amp; cstr)
{
    const T* a = reinterpret_cast&lt;const T*&gt;(cstr.c_str());
    return *a;
}

template&lt;&gt;
string DeSerialize&lt;string&gt;(const string&amp; cstr)
{
    return DeSerialize&lt;char*&gt;(cstr);
}

int _tmain(int argc, _TCHAR* argv[])
{
    int x = 97;
    string c = Serialize&lt;int&gt;(x);
    cout &lt;&lt; DeSerialize&lt;int&gt;(c) &lt;&lt; endl;

    char g = 'g';
    string c2 = Serialize&lt;char&gt;(g);
    cout &lt;&lt; DeSerialize&lt;char&gt;(c2) &lt;&lt; endl;

    string k = "blabla";
    string c3 = Serialize&lt;const char*&gt;(k.c_str());
    cout &lt;&lt; DeSerialize&lt;char*&gt;(c3) &lt;&lt; endl;

    string ka = "string";
    string c4 = Serialize&lt;string&gt;(ka);
    cout &lt;&lt; (DeSerialize&lt;string&gt;(c4)).c_str();

    system("PAUSE");
    return EXIT_SUCCESS;
}
First of all, fundamentally: std::string is a data type to hold text. Exclusively. It should not be used to hold binary data. Use a std::vector&lt;(unsigned) char&gt; for that.

Secondly, you are using heap allocation without needing to:

T* pt = new T(t);


This makes no sense at all, and introduces the potential of a memory leak. You could simply make a copy – but you don’t even need to do that. Just work on the original data.

Next, about naming; it’s general convention in C++ to use underscore_separated_names rather than camelCase or PascalCase. This is only a convention but I’d follow it unless there’s a very compelling reason not to.

Also on the topic of naming: returnSize is redundant, return has no place in the name. Rename it to object_size or something along those lines. You are also inconsistent in your naming convention here.

To get the size of a zero-terminated string, use std::strlen, that’s more efficient than converting to a std::string.

Finally, the code simply doesn’t work. It creates a bit-by-bit shallow representation. That only works for simple composite objects, it no longer works for objects that use pointers or references internally – you’ve already noticed that, because otherwise you wouldn’t need to create a special chase for char* and std::string. Incidentally, for the case of char* you specialise returnSize but for the case of std::string you specialise Serialize and DeSerialize. That’s asymmetrical and means that you have several places that might require changing when new types are added. You should reduce this to a single point which requires specialisation.

Ignoring that, I’d rewrite the code as follows:

#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

typedef unsigned char byte_t;
typedef std::vector&lt;byte_t&gt; buffer;

std::size_t object_size(const char* s) {
    return std::strlen(s);
};

template&lt;typename T&gt;
std::size_t object_size(T const&amp; obj) {
    return sizeof(obj);
};

template&lt;typename T&gt;
buffer serialize(const T&amp; obj) {
    std::size_t size = object_size(obj);
    buffer buf(size);

    byte_t const* obj_begin = reinterpret_cast&lt;byte_t const*&gt;(&amp;obj);
    std::copy(obj_begin, obj_begin + size, buf.begin());

    return buf;
};

template&lt;&gt;
buffer serialize&lt;std::string&gt;(std::string const&amp; str) {
    return serialize(str.c_str());
};

template&lt;typename T&gt;
T deserialize(buffer const&amp; buf) {
    return *reinterpret_cast&lt;const T*&gt;(&amp;buf[0]);
}

template&lt;&gt;
std::string deserialize&lt;std::string&gt;(buffer const&amp; buf) {
    return deserialize&lt;char*&gt;(buf);
}

int main() {
    using std::cout;

    int x = 97;
    buffer c = serialize(x);
    cout &lt;&lt; deserialize&lt;int&gt;(c) &lt;&lt; "\n";

    char g = 'g';
    buffer c2 = serialize(g);
    cout &lt;&lt; deserialize&lt;char&gt;(c2) &lt;&lt; "\n";

    std::string k = "blabla";
    buffer c3 = serialize(k.c_str());
    cout &lt;&lt; deserialize&lt;char*&gt;(c3) &lt;&lt; "\n";

    std::string ka = "string";
    buffer c4 = serialize(ka);
    cout &lt;&lt; deserialize&lt;std::string&gt;(c4) &lt;&lt; "\n";
}


… but like I said, this solution doesn’t generalise and is pretty useless in practice. Have a look at Boost.Serialization for a proper implementation. Unfortunately this is quite a complex problem.