当我宣布这样的结构时:
#pragma pack(1)
structure MyStruct{
uint32_t first;
uint8_t second;
};
#pragma pack()
我显然希望它占用5个字节的内存。那么这样的矢量将如何表现:
std::vector<MyStruct> MyVec;
或者这样的地图:
std::map<MyStruct> MyMap;
他们会遵守要求的协调吗?我可以强制STL结构这样做吗?
答案 0 :(得分:5)
条件是某些编译器可以完全忽略#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
答案 1 :(得分:4)
std :: vector需要与相同类型的plain C = style数组布局兼容。所以它别无选择,只能将它们放在你为结构管理的大小上。
对于其他基于节点的集合,由实现如何创建节点,在那里出现多少字节。
答案 2 :(得分:1)
尺寸真的是个问题吗?听起来像是过早优化。
在任何情况下,对于std::vector
,它通常(依赖于实现)包含2个成员变量:它的大小和指向数据的指针。因此,除非你有很多它们,否则包装不会有太大变化(在你要求打包之前,数据不会影响任何东西,因为它无论如何都是连续的内存块,因为它必须与C兼容)。 / p>
对于地图,我不太确定它的内部结构,但是再次打包可能不会像IIRC那样影响它通常被实现为平衡树。再说一遍,除非你有很多很多,在这里获得的不多。
编辑:此外,我已经弹出MSVC矢量标题,似乎有指令忽略编译指示打包(即文件顶部的pragma push和底部的pragma pop)。