在发生堆栈溢出之前剩余堆栈的大小
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!)。
【讨论】:
混合calloc
和alloca
是个坏消息,因为一个初始化数据,另一个不初始化。这可能会引入奇怪的错误。
好的,可以是malloc
& alloca
。【参考方案2】:
如果您没有使用线程,或者如果您知道您的代码在主堆栈上执行,那么
-
进入 main 时记录当前堆栈指针
在您的例程中,获取当前堆栈限制(请参阅
man getrlimit
)
比较当前堆栈指针与步骤 1 中记录的堆栈指针与步骤 2 中的限制之间的差异。
如果您正在使用线程并且可能在主线程以外的线程上执行,请参阅man pthread_getattr_np
【讨论】:
以上是关于在发生堆栈溢出之前剩余堆栈的大小的主要内容,如果未能解决你的问题,请参考以下文章