【问题标题】:Memory Conservation with Manual Bit Fields vs. std::bitset手动位域与 std::bitset 的内存保护
【发布时间】:2018-05-25 18:06:48
【问题描述】:

我正在学习位标志和使用位运算符手动创建位字段。然后我遇到了位集,这似乎是一种更简单、更清洁的存储位字段的方法。我理解使用位字段的价值,以尽量减少内存使用。但是,在测试 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 吗?

【问题讨论】:

  • bitset 具有与unsigned long long 之间的转换,因此在内部存储该类型并非不合理。如果您需要bitset&lt;1000&gt;,该类型也更方便。如果您只需要一些位,无符号字符可能会更好。
  • Bo,您是说在处理大量要管理的位时,bitset 会得到回报吗?但是为了尽量减少内存使用,我应该坚持手动位移吗?
  • 如果你使用很少的位并且最小的空间比现成的类的便利性更重要,那么可以。一些编译器可能会优化小bitset 的大小,但不是所有人。
  • @LoganWest -- 好吧,你真的不能指望一个有成员的类的大小是一个字节。

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


【解决方案1】:

为了尽可能减少内存占用,您不应使用std::bitset。它可能需要比等效有效大小的普通内置类型(如charint)更多的内存。因此,它可能有内存开销,但具体多少取决于实现。

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

关于位摆弄的旁注:考虑到以这种方式摆弄位的陷阱,您真的可以证明这种容易出错的方法而不是使用std::bitset 甚至像intbool 这样的类型吗?除非你的资源极度受限(例如 MCU / DSP 编程),否则我认为你不能。

玩比特的会被咬,玩字节的会被咬。


顺便说一句,您使用位运算符声明和操作的char bitField 是一个位域,但它不是 C++ 语言的位域概念,如下所示:

struct BitField{
    unsigned char flag1 : 1, flag2 : 1, flag3 : 1;
}

简单地说,它是一种数据结构,其数据成员被细分为单独的变量。在这种情况下,(大概)8 位的unsigned char 用于创建三个 1 位变量(flag1flag2flag3)。它被明确细分,但归根结底,这只是编译器/语言辅助的位摆弄,类似于您在上面所做的。你可以read more about bit fields here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 2023-03-28
    • 2019-10-24
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    相关资源
    最近更新 更多