C++中bitset的大小是多少?

18

我想知道bitset实际上是如何分配内存的。我从一些博客中读到它以位(bit)的形式占用内存。但是当我运行以下代码时:

   bitset<3> bits = 001;
   cout<<sizeof(bits);
我得到的输出是4。这背后的解释是什么?

另外,在C++中是否有一种方法可以分配位空间?

13
你不能在比特级别上分配空间,因为这不是C++抽象机制的工作方式。就像你不能在超市买半个香蕉一样,你也不能分配半个字节的空间。 - user1203803
1
它将四舍五入到存储N位所需的最小字节数,至少。编译器将添加对齐和其他内容以使访问数据更快,但它具体如何实现是由实现定义的。 - user1203803
2
“另外,在C++中有没有一种方法可以分配位空间?”是的,但您一次只能分配8个。 - Luchian Grigore
3
不一定总是8,这取决于CHAR_BIT - user1203803
3
@LuchianGrigore s/追求卖弄学问/正确性/ - user1203803
显示剩余2条评论
5个回答

16

你可以近似计算 bitset<N> 的大小为:

  1. 如果内部表示是32位的(例如在32位系统上的无符号),则为 4 * ((N + 31) / 32)
  2. 如果内部表示是64位的(例如在64位系统上的无符号长整型),则为 8 * ((N + 63) / 64)

看起来第一种情况是正确的: 4 * ((3 + 31) / 32)4


你能详细解释一下为什么是(N + 31) / 32吗?谢谢。 - Deqing
@Deqing 这是一种计算整数分子/分母表达式的上限值的方法。要获取 ceil(N/D) - 您需要使用此表达式:(N + D - 1) / D。请参见:31==32-1。我需要 N/32 的上限值,因此我使用这个技巧来获取它... - PiotrNycz
1
公式 4 * ((N + 31) / 32) 对于 n = 3,40 可以使用,但是当 n = 66 时失败了。看来这里没有确定性的公式... - daparic
@ifelsemonkey - 你的意思是 sizeof(std::bitset<66>) 不是 4 * (66+31)/32,这个结果是12吗?也许在某些数字(比如66)以上,“你的”bitset内部会改变为 uint64_t[] 数组 - 所以它的大小是 8 * (66+63)/64,即16? - PiotrNycz
@ifelsemonkey - 无论如何 - 我们无法百分之百地预测bitset<N>的大小 - 因为它的内部表示可能会因为新版本的std库选择其他内部表示而发生变化。因此,我的答案只是实际值的近似值(我使用了这个动词)。 - PiotrNycz

8
我得到的输出是4,背后的原因是什么?
标准中没有关于如何实现bitset的信息。它的实现是定义好的,查看您编译器的bitset头文件。
此外,C++中是否有一种方法来分配位空间?
不,C++中没有一种方法可以分配位空间。

8

您的CPU不是按位操作,而是按字节和单词操作。在您的情况下,sizeof(bits)的结果为4,因为编译器决定将此数据结构对齐到4个字节。


1
通常在32位处理器上,编译器会将分配的内存大小设置为4字节的倍数,因此大于3/8的最近的4的倍数是4字节。

0

你不能单独寻址位,最小可寻址单位是字节。因此,不,你无法精确地分配位。

另一件事是填充 - 你几乎总是会获得比你要求的更多的字节分配,这是为了优化目的。在32位边界上不寻址字节通常很昂贵,在x64 CPU上不在64位边界上寻址字节会导致异常。(谈到英特尔平台。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接