当我声明这样一个结构时:
#pragma pack(1)
structure MyStruct{
uint32_t first;
uint8_t second;
};
#pragma pack()
我显然希望它会占用 5 个字节的内存。那么这样的向量将如何表现:
std::vector<MyStruct> MyVec;
或者这样的地图:
std::map<MyStruct> MyMap;
他们会服从要求的对齐吗?我可以强制 STL 结构这样做吗?
当我声明这样一个结构时:
#pragma pack(1)
structure MyStruct{
uint32_t first;
uint8_t second;
};
#pragma pack()
我显然希望它会占用 5 个字节的内存。那么这样的向量将如何表现:
std::vector<MyStruct> MyVec;
或者这样的地图:
std::map<MyStruct> MyMap;
他们会服从要求的对齐吗?我可以强制 STL 结构这样做吗?
附带条件是某些编译器可以#pragma
完全忽略,是的,#pragma
影响类型的定义,因此将该类型存储在向量中(例如)意味着存储的内容将被打包。
#include <iostream>
#include <vector>
typedef unsigned long uint32_t;
typedef unsigned char uint8_t;
struct MyStruct0{
uint32_t first;
uint8_t second;
};
#pragma pack(1)
struct MyStruct{
uint32_t first;
uint8_t second;
};
#pragma pack()
int main(){
std::vector<MyStruct0> a;
std::vector<MyStruct> b;
std::cout << "Unpacked size: " << sizeof(a[0]) << "\n";
std::cout << "Packed size: " << sizeof(b[0]) << "\n";
return 0;
}
结果:
Unpacked size: 8
Packed size: 5
std::vector 需要与相同类型的普通 C=style 数组布局兼容。所以它别无选择,只能将它们放置在您为结构管理的大小。
对于其他基于节点的集合,如何创建节点、出现哪些额外字节取决于实现。
尺寸真的是个问题吗?听起来像过早的优化。
在任何情况下,std::vector
它通常(依赖于实现)包含 2 个成员变量:它的大小和指向数据的指针。因此,除非您有很多,否则打包不会有太大变化(在您要求打包数据之前不会影响任何事情,因为它无论如何都是连续的内存块,因为它必须与 C 兼容)。
对于地图,我不太确定它的内部结构,但再次打包可能不会像 IIRC 那样影响太大,它通常被实现为平衡树。再说一次,除非你有很多很多,否则在这里没有太多收获。
编辑:另外,我打开了 MSVC 向量头,似乎有忽略编译指示打包的指令(即文件顶部的编译指示推送和底部的编译指示弹出)。