手动位字段与std :: bitset的内存保护

时间:2018-05-25 18:06:49

标签: c++ bit-fields std-bitset

我正在学习位标志并使用逐位运算符手动创建位字段。然后我遇到了bitsets,似乎是一种更简单,更清晰的存储位字段的方法。我理解使用位字段的价值,尽量减少内存使用量。不过,在测试了sizeof(bitset)之后,我很难理解这是一种更好的方法。

考虑:

#include <bitset>
#include <iostream>

int main ()
{

    // Using Bit Set, Size = 8 Bytes
    const unsigned int i1 = 0;
    const unsigned int i2 = 1;

    std::bitset<8> mySet(0);

    mySet.set(i1);
    mySet.set(i2);

    std::cout << sizeof(mySet) << std::endl;

    // Manually managing bit flags

    const unsigned char t1 = 1 << 0;
    const unsigned char t2 = 1 << 1;

    unsigned char bitField = 0;
    bitField |= t1 | t2;

    std::cout << sizeof(bitField) << std::endl;

    return 0;
}

输出结果为:

mySet是8个字节。 bitField是1个字节。

如果需要最少的内存使用,我不应该使用std :: bitset吗?

1 个答案:

答案 0 :(得分:1)

为了尽可能降低内存占用率,您不应该使用std::bitset。它可能需要比简单内置类型(例如等效有效大小的charint)更多的内存。因此,它可能有内存开销,但多少将取决于实现。

std::bitset的一个主要优点是它可以使您摆脱各种类型的硬件相关实现。理论上,硬件可以使用任何类型的任何表示,只要它满足C ++标准中的某些要求即可。因此,当你依赖unsigned char t1 = 1在内存中00000001时,实际上并没有保证。但是如果你创建一个bitset并正确地初始化它,它就不会给你带来任何令人讨厌的惊喜。

关于bitfiddling的旁注:考虑到以这种方式摆弄比特的陷阱,你能否真正证明这种容易出错的方法,而不是使用std::bitset甚至类似int和{{1}的类型}?除非您的资源受到极大的限制(例如MCU / DSP编程),否则我认为您无法做到。

  

那些玩位的人会被咬,而那些玩字节的玩家将会被击败。

顺便说一下,使用按位运算符声明和操作的bool是一个位字段,但它不是位字段的C ++语言概念,如下所示:

char bitField

简而言之,它是一种数据结构,其数据成员被细分为单独的变量。在这种情况下,(大概)8位的struct BitField{ unsigned char flag1 : 1, flag2 : 1, flag3 : 1; } 用于创建三个1位变量(unsigned charflag1flag2)。它被明确细分,但在一天结束时,这只是编译器/语言辅助的比特摆弄类似于你上面所做的。你可以read more about bit fields here