在 C++ 中定义一个大的位集

Posted

技术标签:

【中文标题】在 C++ 中定义一个大的位集【英文标题】:Define a large bitset in C++ 【发布时间】:2011-08-12 09:56:19 【问题描述】:

在我的程序中,我需要检查我是否已经在一组 2.5*10^9 中生成了一个值。我希望生成大约一半的集合,并且需要有一种快速的方法来检查和更新它。 bitset 在我看来是个好主意,因为它不需要太多内存(每个值 1 位)并且速度很快。

问题是,当我在课堂上定义我的集合时,我得到了一个segmentation fault,因为它的尺寸太大(它适用于较小的尺寸)。

private:
  std::bitset<2500000000UL> cover; // not working
  std::bitset<25000UL> cover; // working

有什么想法吗?

谢谢

PS:如果可能的话,我宁愿不使用外部库。我已经在使用GMP,但我认为他们没有针对大量数字设置的实现。

【问题讨论】:

【参考方案1】:

这将导致分段错误,因为这里的内存是在堆栈而不是堆上分配的。堆栈上的内存分配非常有限,因此无法这样做。 这时候动态内存分配就派上用场了。如果您了解 malloc 的工作原理,您可以按如下方式修改您的代码。

bitset<1000000000> *b;
b = (bitset<1000000000> *)malloc(sizeof(bitset<1000000000>));
b->set(0,1);

完成 bitset 后,使用 delete 关键字将其删除。

【讨论】:

【参考方案2】:

我认为下面的解决方案比使用new更好

    std::vector<std::bitset<2500000000UL>> wrapper(1);
    auto & cover = wrapper[0];//To avoide unnecessary indirection by wrapper[0]

演示

int main()
    std::vector<std::bitset<2500000000UL>> wrapper(1);
    auto & cover = wrapper[0];
    cover[0] = 1;
    std::cout << cover[0] << " " << cover[2500000000UL - 1];

【讨论】:

【参考方案3】:

对于大尺寸使用 std::vector 代替 std::bitset。

【讨论】:

只有在你知道自己在做什么的情况下才使用vector&lt;bool&gt; std::vector 与 bitset 相比性能较差,请参阅:cs.up.ac.za/cs/vpieterse/pub/PieterseEtAl_SAICSIT2010.pdf @math:一项有趣的研究,但现在有点过时了。尽管这篇论文只有 7 年的历史,但研究人员使用的是当时大约 3 岁(现在 10 岁)的 MinGW 版本。我想知道标准库的更现代实现的基准测试是否会产生不同的结果。此外,代码并未作为研究的一部分发布,因此很难确定是否可以改进基准测试。【参考方案4】:

这可能不是您的问题,但请尝试使用 new 分配堆上的位集,而不是使用堆栈。

某些系统会限制堆栈的大小,这可能会给您带来问题。

【讨论】:

你可以在这里找到原因的解释:***.com/questions/4156538/…

以上是关于在 C++ 中定义一个大的位集的主要内容,如果未能解决你的问题,请参考以下文章

用不同大小的位集替换所有内部位集

在初始化时定义位集大小?

移动 Java 位集

比较位集的最快方法(位集上的 < 运算符)?

在 SSE 中使用位集的实现和性能

C++ - 如何左/右循环移位一个位集?