pragma打包一个stl容器

时间:2013-07-01 16:42:50

标签: c++ stl memory-alignment

当我宣布这样的结构时:

#pragma pack(1)
structure MyStruct{
    uint32_t first;
    uint8_t second;
};
#pragma pack()

我显然希望它占用5个字节的内存。那么这样的矢量将如何表现:

std::vector<MyStruct> MyVec;

或者这样的地图:

std::map<MyStruct> MyMap;

他们会遵守要求的协调吗?我可以强制STL结构这样做吗?

3 个答案:

答案 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)。