De-/Serialization of structs representing TCP messages I wrote two template functions to serialize and deserialize structs representing messages to be sent and received via a TCP socket:
/*
 * Convert a byte string into a packet.
 */
template &lt;typename PacketType&gt;
PacketType deserialize(std::string &amp;buf, bool partialProcessing = false)
{
    PacketType packet;
    size_t bufSize = buf.length();
    size_t packetSize = sizeof packet;

    if (packetSize &gt; bufSize)
        std::cerr &lt;&lt; &quot;Packet larger than buffer size. Partial read: &quot; &lt;&lt; (packetSize - bufSize) &lt;&lt; std::endl;

    if (packetSize &lt; bufSize &amp;&amp; !partialProcessing)
        std::cerr &lt;&lt; &quot;Packet smaller than buffer size. Bytes unprocessed: &quot; &lt;&lt; (bufSize - packetSize) &lt;&lt; std::endl;

    auto ptr = reinterpret_cast&lt;char*&gt;(&amp;buf[0]);
    memcpy(&amp;packet, ptr, (packetSize &lt; bufSize) ? packetSize : bufSize);
    return packet;
}

/*
 * Convert a packet into a byte string.
 */
template &lt;typename PacketType&gt;
std::string serialize(PacketType &amp;packet)
{
    auto ptr = reinterpret_cast&lt;char*&gt;(&amp;packet);
    return std::string(ptr, ptr + sizeof packet);
}

The code currently works within a larger project quite well, but I am unsure as to whether it might produce memory leaks due to my usage of pointers and memcpy.
How can I improve this code?
Addendum
Since some of the (great) answers seem to need more context, this is but an excerpt of this revision of a header file within the respective project. The template functions are used internally only i.e. do not constitute an external API.
Your code produces no memory leaks since you're not manually allocating and deleting memory.

Include all headers
Always include all the headers. In this case, you need &lt;iostream&gt;, string, and cstring.

Pass by const reference
You should pass your objects by const reference. For example, const std::string&amp; buf and const PacketType&amp; packet. You can use reinterpret_cast&lt;const char*&gt;.

Use std::memcpy instead of memcpy
If you're including &lt;cstring&gt; (which you should be since you're using C++), you should qualify your C function calls with the std namespace.

Including the C++-style header () guarantees that the entities will be found in namespace std and perhaps in the global namespace.


Compile time checks for POD structs
std::memcpy only does a shallow copy, so it only works on POD structs (i.e. C-style structs).

A Plain Old Data Structure in C++ is an aggregate class that contains only PODS as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type.

For example,
struct Example
{
    int a;
    std::string b;
};

is a non-POD struct since std::string is a non-POD type (has a non trivial copy constructor, non-trivial destructor).
You should make sure that PacketType is a POD struct. You can do this with a compile time check using static_assert.
You can check whether a type is POD, using is_pod type trait (deprecated in C++20) or using is_trivial &amp;&amp; is_standard_layout. Here is a good description of what these terms mean and how they relate to POD types.