条件堆栈分配

时间:2014-02-13 12:41:18

标签: c

我有一个方法将指针T带到有效的内存块。在该方法中,由于已知常量some​​_defined常量很小,因此不会产生堆栈溢出,因此以下是明智的吗?

if (T)
{
    p = T;
    q = T + k;
}
else
{
    unsigned long long TT[2 * some_defined constant];
    p = TT;
    q = TT + k;
}

<code using p and q>

除非我知道该方法被同时调用,否则我绝不会考虑这样做;它被调用五次,每次调用都在一个单独的线程上。进行此类调用的方法使用OMP循环。如果调用OMP循环的调用方法是为了满足所需的额外内存并在T中预先分配,则需要从调用者请求分配10 * some_defined常量字,如果在OMP循环中调用的方法分配2 * some_defined常量然后才能很好地工作。如果有可能出现堆栈溢出的风险,那么可以在堆上分配10 * some_defined常量字后调用top方法。

3 个答案:

答案 0 :(得分:7)

TT数组的生命周期只会延长,直到离开声明它的块(else块)。因此,当访问else块的末尾时,您的代码将导致未定义的行为。

如果将TT的声明移到if语句之上,则代码将是正确的。但是当然即使不需要它也会在堆栈上分配。

如用户自己的评论中所述,您可以根据是否需要使用C99可变长度数组来更改TT的大小:

unsigned long long TT[is_needed ? some_size : 1];

答案 1 :(得分:3)

在这种情况下我会做(伪代码):

void function_which_does_the_job(... p, ... q)
{
    <code using p and q>
}

if (T)
{
    function_which_does_the_job(T, T+k);
}
else
{
    unsigned long long TT[2 * some_defined constant];
    function_which_does_the_job(TT, TT+k);
}

然后你不要重复自己,然而你可以做你想做的事。

如果您的编译器确实不支持VLA,请执行

if (T)
{
    function_which_does_the_job(T, T+k);
}
else
{
    unsigned long long * TT = malloc(2 * some_defined constant * sizeof(*TT));
    function_which_does_the_job(TT, TT+k);
    free(TT);
}

代替。

(当然,您还必须将其他变量传递给函数;如果其中包含k,您可以省略q并在函数中确定它。)

答案 2 :(得分:1)

您可以使用alloca函数在堆栈上动态分配字节。与C99可变长度数组一样,它无法检测分配失败,因此除非您确保分配的数量很小,否则它会承担一定的风险。

if(T) {
    p = T;
    q = T + k;
} else {
    p = alloca(2 * some_defined constant * sizeof(long long));
    q = p + k;
}
/* use p and q until the end of the function scope */