STL位集移位运算符导致分段错误

时间:2020-05-19 01:30:20

标签: c++ stl segmentation-fault bitset

考虑以下代码:

#include <iostream>
#include <bitset>

using namespace std;

int main() {
  const int N = 1e9;
  bitset<N> st;
  st << 999;
  cout << st.test(0);
}

(请注意,使用的是运算符<<,而不是<<=。我需要的是<<。也不要删除cout行,因为那样会不会出现SegFault。我相信是由于编译器的优化。

这会导致我的机器出现分段错误。但是,将999更改为1后,不会引发异常。问题是什么,引发了什么类型的异常,又该如何解决呢?

另一个奇怪的是,代码可以在某些计算机上运行,​​包括ideone服务器。但是,不是我的:

gcc version 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2)

所以请解释为什么该问题在某些计算机上无法重现?

1 个答案:

答案 0 :(得分:3)

原始代码很可能导致堆栈溢出:该位集可能使用数百兆的内存,而系统通常默认为几兆字节的堆栈大小。

超过堆栈限制的行为在系统之间可能有所不同;在某些情况下,它可能看起来像预期的那样工作,而在另一些情况下,则可能存在某种信号或崩溃或不可预测的行为。

您可以使用static bitset<N> st;或动态分配来固定位集的存储。但是,还有另一个问题。声明:

st << 999;

调用overloaded operator function,它按值返回一个临时位,因此该临时位仍会导致堆栈溢出。

为避免这种情况,您将不必致电st << 999。您没有说过要使用此代码做什么,但是如果要就地修改位集,可以编写st <<= 999;。如果您打算在不更改原始位集的情况下进行更改后的副本,请首先进行副本(使用静态或动态分配),然后在副本上调用<<= 999

相关问题