请考虑以下代码:
int main() {
int ar[100]={0};
int n = 100;
recurFun(ar, n);
return 0;
}
void recurFun(const int ar[], int n) {
if(some condition) {
//some code here to manipulate ar[]...
return ;
}
int i;
//some code to manipulate i
recurFun(ar, i)
}
我听说递归函数每次调用自己都会产生自己的变量,因此我希望ar
多次创建,可能需要大量的内存使用,对吧?
如果我将ar
声明为全局数组,如下所示:
int ar[100]={0};
int main() {
int n = 100;
recurFun(n);
return 0;
}
void recurFun(int n) {
if(some condition) {
//some code here to manipulate ar[]...
return ;
}
int i;
//some code to manipulate i
recurFun(i)
}
这会更节省内存吗?因为我认为递归函数没有理由复制全局变量。但是,会因为许多递归函数访问同一个数组而变慢,因此会产生一些开销。
答案 0 :(得分:3)
const int ar[]
不复制数组,它将数组衰减为指向第一个元素的指针。
你的全局数组解决方案的内存效率要高得多,因为它不会在堆栈变量中传递这个指针,但这并不重要。堆栈空间是空闲的,直到你溢出它,并且每次调用是否使用一个额外的指针不应该是堆栈溢出之间的区别。
答案 1 :(得分:0)
我听说递归函数每次调用自己都会产生自己的变量,因此我希望ar会多次创建并且可能需要大量的内存使用,对吗?
这是不正确的。每次调用递归函数都会使用该函数的一组新local
变量 - 它与您的全局数据无关。因此,每次调用递归函数时都不会创建ar
。
答案 2 :(得分:0)
因此我希望ar可以多次创建并且可能需要大量内存使用,对吧?
不,那不是真的。
当您调用recurFun
时,只有指向数组第一个元素的指针才会传递给该函数。通过将数组传递给recurFun
,您不应该看到任何性能差异。
答案 3 :(得分:0)
不应该受到惩罚。
整个数组本身不会被复制(指针),并且由于其他参数等原因,无论如何都必须调整堆栈的大小。
答案 4 :(得分:0)
我想我可能会在这个问题上多加一点来解释内存的分配位置和方式。
int main() { int ar[100]={0}; recurFun(ar, 100); }
void recurFun(const int ar[], int n)
这将在运行时堆栈分配你的数组,并且对于recurFun
的每次递归调用,它将堆栈分配一个指针和一个int(在最坏的情况下!常见的情况可能是尾递归是可能的它可以重用堆栈。)
int ar[100]={0};
int main() { recurFun(ar, 100); }
void recurFun(int n)
这将在数据段的启动时分配您的数组,并且对于recurFun
的每次递归调用,它将堆栈分配一个int(在最坏的情况下!与上面相同)。根据您的链接器设置,对此的访问将通过间接表进行,因此每次使用都需要2个指针访问。
int main() { int ar[100]= new int[100]; recurFun(ar, 100); }
void recurFun(const int ar[], int n)
这将在运行时动态分配您的数组在动态分配的内存段中,并且对于recurFun
的每次递归调用,它将堆栈分配指针和int(在最坏的情况下!与上面相同)。
除非数组非常大(> 100kb),否则首选方法。