linux如何防止堆空间被覆盖,如何让更多的内存和避免大量递归堆栈溢出?

虽然其他答案谈谈如何要么避免递归完全,或如何使用尾递归,或如何简单地设置一个较大的堆栈大小,我认为完整性,这是值得考虑的内存使用模式(以回答“如何让更多的内存...在很多递归上”)。

出于习惯,许多程序员将分配缓冲区递归函数里面,并重新分配新的缓冲区,当函数被递归调用:

int recursive_function(int x)

{

if (1 == x)

return 1;

int scratchpad[100];

... // use scratchpad

return recursive_function(x-1) + scratchpad[x-1];

}

由于这是一个一次性的样品,我不会打扰担心关于无效输入(负值,大于100的值),我会假设有人提出关于编程的问题要么知道如何做,要么足够聪明以找出答案。

重要这里的一点是,scratchpad堆栈每一次recursive_function()被称为的占用400个字节(32位机器上,800个字节的64位计算机上),所以如果recursive_function()被递归调用100倍,然后40000字节(或80000个字节的64位计算机上)的堆栈空间被用于缓存,它很可能,你可以修改函数重用每次调用同一个缓冲区:

int recursive_function(int x, int* buffer, int buffer_length)

{

if (1 == x)

return 1;

... // use buffer (and buffer_length to avoid overflow)

int temp_value = buffer[x-1];

return recursive_function(x-1, buffer, buffer_length) + temp_value;

}

当然你可以改为使用std::vector,它为你处理一些细节,以防止内存泄漏和缓冲区溢出(并且,对于记录,将数据保存在堆上[见脚注],这意味着它可能会使用较少的堆栈空间)。

40k甚至80k可能看起来不多,但事情可以加起来。如果该函数没有其他堆栈分配变量,那么这可以支配堆栈空间(也就是说,如果它不是用于缓冲区占用的额外空间,则可能可以调用该函数的次数)。

这看起来很明显,即使在非递归函数中也是如此,即but it does come up。另外,缓冲区并不总是与数组一样明显。例如,它们可能是字符串或对象。

脚注:STL容器,比如数组不一定提上堆的所有数据。他们实际上采用模板参数来指定使用的内存分配;它只是默认使用的分配器将数据放在堆上。很明显,除非你指定一个以某种方式将数据放入堆栈的分配器,否则最终结果将是相同的:使用STL容器可能比使用堆栈分配的数组或对象使用更少的内存。

我说“可能”,因为虽然数据保存在堆(或其他地方),但容器只能通过它在内部保存的指针访问该数据,如果容器在堆栈上,那么这些指针将驻留在堆栈和这些指针占用空间。因此,一个或两个元素std::vector实际上可能占用堆栈上的空间多于对应的数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值