繁体   English   中英

如果声明了一个大变量,为什么C程序会崩溃?

[英]Why does a C program crash if a large variable is declared?

我在Microsoft Visual Studio Express 2012中编译了以下C程序:

int main() {
   int a[300000];
   return 0;
}

这与msvcr110d.dll中的堆栈溢出崩溃!__ crtFlsGetValue()。

如果我将数组大小从300,000更改为200,000它可以正常工作(因为这个简单的程序可以说是“工作”,因为它没有做任何事情)。

我在Windows 7上运行,并且还在Cygwin下使用gcc尝试了这个并且它产生了相同的行为(在这种情况下是一个seg错误)。

有没有搞错?

C中自动对象使用的空间大小存在特定于平台的限制(“堆栈大小”)。 大于该大小的对象(在嵌入式平台上可能是几千字节,在台式机上可能是几兆字节)不能被声明为自动对象。 使它们变为静态或动态。

类似地,函数调用的深度存在限制,特别是在递归方面。

检查编译器和/或平台文档,以获取有关实际大小的详细信息,以及如何更改它的详细信息。 (例如在Linux上检查ulimit 。)

因为它被分配在堆栈上并且堆栈的大小有限,显然不足以容纳300000个整数。

使用堆分配a malloc

int* a = malloc(sizeof(int) * 300000);
// ...
free(a);

堆可以比堆栈容纳更多。

局部变量声明堆栈中的空间。 所以,如果你分配足够大的东西,堆栈将不可避免地溢出。

由于对每个进程可用的虚拟地址空间量的有限限制,线程堆栈的大小传统上受操作系统的限制。

由于分配给线程堆栈的虚拟地址空间一旦分配就无法更改,除了为每个线程分配一个相当大但有限的块之外没有其他策略 - 即使大多数线程只使用很少的线程。

类似地,对进程允许生成的线程数也有一个有限的限制。

猜测,这里的限制是1MB,然后Windows将线程数限制为 - 比如说 - 256,这意味着32位进程可用的256MB 3GB虚拟地址空间被分配给线程堆栈 - 或者放入另一个方式,1/12。

在64位系统上,显然有更多的虚拟空间可供使用,但为了快速检测 - 并终止 - 无限递归,有一个限制仍然是明智的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM