在发生堆栈溢出之前剩余堆栈的大小

Posted

技术标签:

【中文标题】在发生堆栈溢出之前剩余堆栈的大小【英文标题】:Size of remaining stack until a stack overflow occurs 【发布时间】:2012-01-12 00:37:06 【问题描述】:

在 Linux 上,使用 C,假设我有一个动态确定的 n 命名我必须在一个数组中存储的元素数量 (int my_array[n]) 只是在很短的一段时间内,比如一个函数调用,由此被调用的函数只使用很少的内存(几百字节)。

大多数情况下,n 很少,只有十分之一。但有时n 可能很大,高达 1000 或 1'000'000。

我如何计算,我的堆栈是否可以容纳n*o + p 字节而不溢出?

基本上:我的堆栈上还剩下多少字节?

【问题讨论】:

Checking available stack size in C 的可能重复项 @BrendanLong,我看到了这个问题,但正如它所说“我正在使用带有 GCC 3.4.5 (mingw-special vista r3) 的 MinGW”,答案有点以 Windows 为中心。我的问题是以 Linux/*nix 为中心。 ;-) 为什么不能使用getrusage()getrlimit() @sverre,如果您向我解释 getrusage 和 getrlimit,我会很高兴。 getrusage 的手册页说“ru_isrss (unmaintained) This field is currently used on Linux”。 @kay - 查看该页面上的第 4 个响应。 【参考方案1】:

确实,checking available stack 问题给出了很好的答案。

但更务实的答案是:不要在调用堆栈上分配大数据

在您的情况下,您可以不同地处理n<100 时的情况(然后在堆栈上分配,也许通过alloca 有意义)和n>=100 时的情况(然后,使用@ 在堆上分配987654326@(或calloc)别忘了free它)。将阈值 100 设为 #define-d 常量。

在当前的笔记本电脑或台式机上,call stack 上的典型调用帧最多应为几千字节(如果您有递归或线程,最好更少)。总堆栈空间通常最多只有几兆字节(有时甚至更少:在内核内部,每个堆栈通常为 4 KB!)。

【讨论】:

混合callocalloca 是个坏消息,因为一个初始化数据,另一个不初始化。这可能会引入奇怪的错误。 好的,可以是malloc & alloca【参考方案2】:

如果您没有使用线程,或者如果您知道您的代码在主堆栈上执行,那么

    进入 main 时记录当前堆栈指针 在您的例程中,获取当前堆栈限制(请参阅man getrlimit) 比较当前堆栈指针与步骤 1 中记录的堆栈指针与步骤 2 中的限制之间的差异。

如果您正在使用线程并且可能在主线程以外的线程上执行,请参阅man pthread_getattr_np

【讨论】:

以上是关于在发生堆栈溢出之前剩余堆栈的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中处理或避免堆栈溢出

堆栈溢出一般是由啥原因导致的?

C语言画图理解堆栈溢出

增加堆栈保留大小并不能防止堆栈溢出

FreeRTOS中的任务堆栈溢出检测机制

由于堆栈溢出,C 中通常会发生啥?