我有一个方法将指针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方法。
答案 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 */