struct TestClass
{
int a;
double b;
};
这个结构体占用的内存的大小是16字节(windows下),它在内存里面按照double的字节大小对齐。
TestClass demo = {1, 1.1};
定义一个对象后,通过网络把这个demo对象发出去。
write(sockfd, &demo, sizeof(demo));
这样是发出去16个字节对吧?这样发出去的数据就包含了编译器字节对齐插进去的4个字节了吧?我的理解对吗?
如果把这个demo对象序列化为二进制的话是不是就是把demo里的int和double的值复制到一个缓冲区里,这样这个缓冲区的里面的值的长度就是12字节了(int + double)。这样的话,通过网络发送这个缓冲区里的数据的话就不包含字节对齐的值了吧,这就是序列化的意义吗?
求大神告诉我理解的对不对?不对的话我的哪些地方没有理解对呢?
The memory layout is not portable. And there are still gaps.
Serialization is for portability. Various languages follow the serialization method, so objects can be deserialized and an object can be serialized. In this way, it can be used across Language interaction.
The significance of serialization is to define a correspondence between data in a program and a byte string (and its inverse relationship) for storage and transmission. This relationship is a standard and has nothing to do with implementation or platform (no matter what CPU, operating system, compiler, or programming language you use, the interpretation method of serialized data is predefined).
Of course there are serialization solutions that are limited to specific programming languages (such as Python's pickle). But that's just an implementation in that language. In theory, you can write programs in other languages to interpret this data.
1.
write(sockfd, &demo, sizeof(demo));
It is indeed 16 bytes sent out like this.
But you have to understand that the write function itself has nothing to do with byte alignment. The write function itself only knows which address to start from and how many bytes to send. The write function itself does not know the structure of your demo. The reason why 16 bytes are sent is because sizeof(demo) calculates 16 bytes.
2. Serialization is provided by some programming language libraries, which can map data into bytes for storage or transmission. Deserialization is to reload and restore from bytes. These two processes are provided by the library itself, and the developers of the library will ensure that this process is portable on all platforms.
To digress, it is best to explicitly pack network programming. For example, a 64-bit machine is designed according to 64-bit structure
struct TestClass
{
};
Otherwise, the results compiled with different compilation options will be different, and may not always be 16 bytes.
Since the poster is so humbly asking for advice, let me tell you what the poster does not understand correctly:
The demo struct is already binary, and write(sockfd, &demo, sizeof(demo)) sends binary data.
Copy? Buffer? Where did the original poster get these concepts? It’s not like this at all...
To save memory and not waste a single byte, you can use the macro #pragma pack(1).
http://www.cppblog.com/vczh/archive/2009/03/10/76098.html
See my blog for detailed answers