为什么大型静态数组会产生seg-fault,但动态不会? (C ++)

时间:2013-04-29 01:11:10

标签: c++ arrays dynamic static

以下代码给出了分段错误:

bool primeNums[100000000]; // index corresponds to number, t = prime, f = not prime

for (int i = 0; i < 100000000; ++i)
{
    primeNums[i] = false;
}

但是,如果我将数组声明更改为动态:

bool *primeNums = new bool[100000000];

我没有遇到段错误。我有一个大致的想法,为什么会这样:在第一个例子中,内存被放在堆栈上,而在动态情况下,它被放在堆上。

你能更详细地解释一下吗?

4 个答案:

答案 0 :(得分:5)

bool primeNums[100000000];

用完了所有stack空间,因此,由于没有足够的堆栈空间来分配大尺寸的静态数组,因此会出现分段错误。

动态数组在heap上分配,因此,不容易得到分段错误。动态数组是使用C ++中的new创建的,它将调用operator new来分配内存,然后调用构造函数来初始化已分配的内存。

有关operator new工作原理的更多信息,请参阅以下标准[new.delete.single]:

  

必需的行为:

     

将非空指针返回到适当对齐的存储(3.7.3),或否则抛出bad_alloc异常。此要求绑定在此函数的替换版本上。

     

默认行为:

     

- 执行循环:在循环内,该函数首先尝试分配所请求的存储。是否未指定尝试是否涉及调用标准C库函数malloc。

     

- 如果尝试成功,则返回指向已分配存储的指针。否则,如果set_new_handler()的最后一个参数是空指针,则抛出bad_alloc。

     

- 否则,该函数调用当前的new_handler(18.4.2.2)。如果被调用函数返回,则循环重复。

     

- 当尝试分配所请求的存储成功或被调用的new_handler函数未返回时,循环终止。

因此使用带有new的动态数组,当没有足够的空间时,它会默认抛出bad_alloc,在这种情况下,当您的数组大小时,您将看到异常而不是分段错误是巨大的,最好使用动态数组或标准容器,如矢量。

答案 1 :(得分:1)

bool primeNums[100000000];

此声明在stack space中分配内存。堆栈空间是在启动应用程序时分配的内存块。它通常在几千字节或兆字节的范围内(这取决于语言实现,编译器,操作系统和其他因素)。

此空间用于存储本地和静态变量,因此您必须温和且不要过度使用它。因为这是一个堆栈,所有分配都是连续的(分配之间没有空的空间)。

bool *primeNums = new bool[100000000];

在这种情况下,分配的内存是堆。这是无空间的,可以分配大量的新内存。

答案 2 :(得分:0)

某些编译器或操作系统会限制堆栈的大小。在Windows上,默认值为1 MB,但可以更改。

答案 3 :(得分:0)

在第一种情况下,你在堆栈上分配内存:

bool primeNums[100000000]; // put 100000000 bools on stack

for (int i = 0; i < 100000000; ++i)
{
    primeNums[i] = false;
}

然而这是堆上的分配:

bool *primeNums = new bool[100000000]; // put 100000000 bools in the heap

并且由于堆栈(非常)受限,这就是segfault的原因