如何在使用C语言时计算Linux中剩余的堆栈?

3
我正在开发一个需要大量使用栈内存的程序。在Linux平台上,有没有一种方法可以查找剩余的栈空间?谢谢!

1
如果您正在使用大量的堆栈内存,请考虑改为在堆上分配内存。 - Jesus Ramos
6
我同意 @JesusRamos 的观点。栈空间是一种“你要问就说明你负担不起”的情况。 - Matthew Flaschen
由于Stack Clashrlimit_stack的行为已经发生了变化。还请查看红帽子公司的问题1463241 - jww
2个回答

6
有没有一种方法可以找到剩余的堆栈空间?
是的,有:对于主线程,你可以简单地在main函数中记录&argc到某个全局变量中(例如int *g_addr_argc),然后调用getrlimit(RLIMIT_STACK, ...)并将某些本地地址与其进行比较,例如:
char a_local;
struct rlimit rlim_stack;

if (getrlimit(RLIMIT_STACK, &rlim_stack) == 0 &&
    rlim_stack.rlim_cur != RLIM_INFINITY &&
    (uintptr_t)g_addr_argc - (uintptr_t)&a_local > rlim_stack.rlim_cur - 8192) {
  fprintf(stderr, "Danger: getting too close to the stack limit\n");
}

这只适用于主线程。如果您的应用程序是多线程的,您可以使用pthread_getattr_np来查找有关当前线程堆栈的信息。


2

您可以在代码中使用 setrlimit 来自定义堆栈大小。这样您就不用再猜测了,而且可以根据需要适当增加堆栈大小(在合理范围内)。

#include <sys/resource.h>

int main (int argc, char **argv)
{
    const rlim_t kStackSize = 16 * 1024 * 1024;   // min stack size = 16 MB
    struct rlimit rl;
    int result;

    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == 0)
    {
        if (rl.rlim_cur < kStackSize)
        {
            rl.rlim_cur = kStackSize;
            result = setrlimit(RLIMIT_STACK, &rl);
            if (result != 0)
            {
                fprintf(stderr, "setrlimit returned result = %d\n", result);
            }
        }
    }

    // ...

    return 0;
}

你可以自己设置堆栈大小,但这可能并不是非常有用。例如,如果你在递归下降解析器中处理任意用户输入,那么无论你分配多大的堆栈,用户都可以提供超过该堆栈大小的输入。更有用的是检测到即将耗尽堆栈并停止解析,而不是耗尽堆栈并崩溃。 - Employed Russian
1
@EmployedRussian 这只是我要表达的一半。另一半是,一旦你知道你的堆栈有多大(因为你设置了它),你就可以知道还剩下多少。 - Mahmoud Al-Qudsi
@MahmoudAl-Qudsi:但是你不能增加堆栈的大小。这就是Matthew试图表达的意思。 - Julie in Austin
@JulieinAustin 不是的。这里有两种不同的情况:1)您可以设置堆栈大小并监视使用情况,以确保不超过(抵消EmployedRussian的反对意见)。2)由于权限问题,有时无法设置堆栈大小,这是MatthewFlaschen的观点,并且完全有效。 - Mahmoud Al-Qudsi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接