C:堆栈太大会导致分段错误吗?

C:堆栈太大会导致分段错误吗?,c,memory-management,C,Memory Management,我最近调试了一个非常奇怪的问题,它导致了分割错误 基本上,在我将两个声明为局部变量的非常大的数组移动到全局变量后,问题就消失了,这意味着据我所知,我将它们从堆栈移动到了堆空间。其他一切都没有改变。分段错误本身出现在非常旧和稳定的代码中,这些代码也在没有经历任何分段错误的其他程序中共享 这些阵列的总大小约为1.5 MB 太大的堆栈是否可能通过覆盖/弄乱函数指针而导致分段错误 我的感觉是这样的事情应该被编译器捕获,但我绝对没有其他方法来解释这种行为 平台是Linux(Ubuntu 18.04)程序的

我最近调试了一个非常奇怪的问题,它导致了分割错误

基本上,在我将两个声明为局部变量的非常大的数组移动到全局变量后,问题就消失了,这意味着据我所知,我将它们从堆栈移动到了堆空间。其他一切都没有改变。分段错误本身出现在非常旧和稳定的代码中,这些代码也在没有经历任何分段错误的其他程序中共享

这些阵列的总大小约为1.5 MB

太大的堆栈是否可能通过覆盖/弄乱函数指针而导致分段错误

我的感觉是这样的事情应该被编译器捕获,但我绝对没有其他方法来解释这种行为


平台是Linux(Ubuntu 18.04)

程序的堆栈大小是有限的,因此将太多的大型数组声明为局部变量可能会导致堆栈溢出。你所做的是处理这个问题的好方法

编译器通常不会检查它,因为堆栈大小在运行时由操作系统控制,例如Linux系统上的
ulimit-s
getrlimit
/
setrlimit
。有关堆栈大小的说明如下:

RLIMIT_堆栈

进程堆栈的最大大小,以字节为单位。一到这里 限制,生成SIGSEGV信号。为了处理这个信号,需要一个进程 必须使用备用信号堆栈(sigaltstack(2))


因此,在Linux上,堆栈的大小是一个运行时设置,溢出堆栈会显式导致分段冲突。

在调试器中运行堆栈时,它会说什么?是获得合理的堆栈跟踪,还是只获得一个包含一个函数的堆栈跟踪?你试过和valgrind一起运行吗?是的,stackoverflow肯定会导致seg故障以及其他各种奇怪的故障。您是否尝试以不同的方式编译以获得更多的堆栈空间?你的平台是什么?您是否检查了所有数组索引都没有超出范围?您的代码显然是稳定的这一事实并不排除后者(请参阅未定义的行为)。据我所知,默认的主堆栈大小(线程可能不同)在Windows上为1 MiB,在Linux和macOS上为8 MiB。因此,是的,1.5 MB或1.5 MiB的数组将溢出Windows上的默认堆栈,如果与其他大型对象一起使用,则会溢出Linux和macOS上的默认堆栈。@cup:gdb说:无法访问地址处的内存0x7fffff7f6d18@cup:这发生在(非常旧,非常稳定)函数的开始,所以我认为这是一个死胡同。堆栈大小由操作系统控制?还是通过程序的运行时代码?通常,堆栈是在程序启动时设置的,其大小不会动态变化(由操作系统决定)。页面可以启用或交换,但这是另一回事。程序可以请求可执行文件中的堆栈大小。这通常使用链接器选项设置。因此,Linux资源限制不是唯一的控制方法。我手头没有详细资料。@Rolandseus拥有大数组的函数本身可能不足以炸毁堆栈,但可以使堆栈足够靠近,再调用几个小函数就可以将其推到边缘。