为什么我们需要在C ++中使用#pragma pack
typedef
结构?特别是当您在网络通信中使用这些结构时。
答案 0 :(得分:13)
#pragma pack
控制结构成员的对齐方式。常见的默认设置为8,确保长达8个字节的成员在一个大小为其倍数的地址上对齐。例如,双指针或64位指针。读取或写入错误对齐的double可能非常昂贵,如果跨越CPU缓存行边界,通常会慢三倍。这种对齐可以在成员之间产生未使用的空间,称为填充。
这种对齐通常不适合网络框架,它们往往紧密包装而没有任何填充,#pragma pack(push,1)
答案 1 :(得分:0)
#pragma pack指令仅修改声明遵循该指令的结构的成员的当前对齐规则。它不会直接影响结构的对齐,但是通过影响结构成员的对齐,可能会影响整体结构的对齐方式
答案 2 :(得分:0)
如果您只需要让具有相同设置的2个系统相互通信(测试,...),您可以发送结构,只要它们只是POD(普通旧数据)(指针,虚拟表,std ::字符串...不能使用)。所以不需要打包。
如果系统没有相同的设置(或未知),则需要发送协议序列化的数据,因此打包结构不行。最简单的方法是检查有效的protcols是否可用。
答案 3 :(得分:0)
编译器将“填充”结构的字段和子字段,即使用空白的内存块在内存中组织它们,这些内存中间没有任何内容。正如Hans Passant的回答所解释的那样,这样做是为了提高效率。
不同的编译器/目标/优化设置可以填充不同,在不相等的内存表示中转换相同的“逻辑”结构,因此如果两个通信机器在它们之间传递结构,它们可能彼此不理解。
#pragma pack是限制编译器填充自由的方法。
#pragma pack(push,1)命令编译器根本不填充。如果对不同代码中定义的两个相同结构执行此操作,则它们将在内存中以相同的形式表示。然后你可以使用指针和sizeof()通过一些协议在一个应用程序中安全地发送结构的内容,在另一侧获取它并将其写在相同的结构上,同样使用指针和sizeof()。