有没有一种好的方法可以在函数外访问信息?

3

目前,我正在使用C++编写一个递归函数。该函数需要传递一个大数组和几个常量变量才能正常工作。以下是递归结构:

void recurse_objects(std::vector<Object> &objects, int i, int j, double merge_distance, double size_enclosure, double timestep){

    //operations performed

    //recursion performed
    if(j+1 < objects.size()){
        recurse_objects(objects, i, j+1, merge_distance, size_enclosure, timestep);
    }else if(i+2 < objects.size()){
        recurse_objects(objects, i+1, i+2, merge_distance, size_enclosure, timestep);
    }

    //more operations performed
}

该函数递归遍历每对独特的对象(i,j)。问题在于,我处理的对象数量达到了500-2000个,函数由于栈空间不足而导致分段错误 - 对于350个以下的对象可以运行。
感觉如果我能将数组和常数变量存储在其他地方,就能节省空间并能够在最后几个对象上运行计算。这个问题有常见的解决方法吗?我所想到的唯一的方法是使用全局变量 - 但这不可行,因为值由系统输入决定,批处理会完全破坏效率,或者将程序改为非递归程序。

1
向量引用中的对象已经存储在其他地方。这是双重的。首先,因为向量使用动态内存,其次,因为有一个单一的向量,其引用被递归传递。 - Jeffrey
4
真正的解决方案是使用迭代解决方案,而不是递归解决方案。 - Jeffrey
我的经验表明,递归函数的调用深度应该与 O(log n) 成正比。就像分治或树遍历算法一样。如果深度是 **O(n)**,则堆栈溢出很容易发生,但通常可以将算法转换为循环。 - prapin
听起来我将不得不使用迭代 - 这个项目的目标是缓存优化,这也是我想尝试递归的唯一原因(除了看起来更清晰)。谢谢大家。 - J M
1个回答

2
如果您的编译器没有执行尾调用优化,运行时间过长的递归函数将始终导致堆栈溢出。减少每个堆栈帧中存储的内存量可以延迟这种不可避免的情况,并使您能够在更大的数据集上运行它,但它们无法解决问题,因为即使是的堆栈帧也会累加。
如果您可以在递归调用后摆脱那些操作,那么这很可能取决于您为优化发送给编译器的标志,您的函数已经朝着尾递归的方向发展。

1
@Richard 真的吗?我认为尾递归优化的重点是,如果您唯一的递归点是 return nextRecursiveCall(...);,那么您可以重用当前堆栈帧来进行 nextRecursiveCall。如果当前调用在 nextRecursiveCall 返回后还有更多操作要执行,我不明白这怎么可能成立。 - Nathan Pierson
@Nathan 对不起,我把那些调用解释为在void情况下等同于return,但你是对的,它们不需要这样做。 - Richard
两个计算都是必要的:第一个计算所有加速度,然后在之后的操作中计算速度。我得把递归分开。可能会选择迭代。 - J M

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