有没有办法在visual studio C ++中增加运行时的堆栈保留大小

时间:2015-02-20 20:35:38

标签: c++ stack

我正在用C ++开发一个.exe求解器。求解器中有一个递归算法,因此我在配置属性 - >链接器 - >系统 - >堆栈保留大小中将堆栈保留大小设置为2 100 000 000。但是当一些客户在他们的机器上运行它时,它会崩溃。它在大多数机器上都能正常工作。我将堆栈保留大小减少到0并要求客户尝试。有用。所以我认为堆栈保留大小应该是问题所在。

现在我有两个问题:

  1. 客户机器的潜在问题是什么?我认为客户可能设置了一个非常小的最大虚拟内存大小。所以我在我的机器上尝试它,在高级系统设置中将虚拟内存的最大大小设置为0 - >性能设置 - >高级 - >虚拟内存 - >客户大小。但是在这种情况下解算器不会崩溃。

  2. 有没有办法在运行时设置堆栈保留大小。如果可以,那么如果解算器在他的机器上崩溃,我可以让客户用ENV覆盖堆栈大小。

  3. PS:添加更多信息。此代码编译为64位而没有设置LARGEADDRESSAWARE选项(我不知道此选项的默认设置)。这段代码在64位机器上运行得非常好。事实上,过去几年中只有一位客户对此次事故抱怨。

2 个答案:

答案 0 :(得分:4)

将堆栈大小设置为2GB是解决此问题的荒谬方法。正确的解决方案是减少递归算法中的堆栈使用,或使用迭代解决方案(可能使用软件堆栈来解决"我们在哪里回到"递归解决的问题)。

一个相对简单的解决方案,在不知道代码实际执行的情况下,将使用std::vector<T> v(size);而不是T v[size]; - 这将使v的大小约为3 *指针大小而不是堆栈上的sizeof(T) * size - 如果你有一些更大的数组,这实际上是一种减少堆栈使用的有用方法。

答案 1 :(得分:3)

崩溃的原因是OS加载器在尝试为新进程设置初始线程时,未能找到2.1GB的连续地址空间来为线程堆栈分配(保留,而不是提交)。 / p>

此故障是不确定的,因为地址空间布局随机化(安全功能)会导致DLL在随机地址加载,这会导致地址空间碎片化。幸运的是,有一个足够大的片段用于你的线程堆栈。否则,在执行任何代码之前立即崩溃。

更改虚拟内存设置无关紧要,因为问题是地址空间,而不是所有进程的最大总虚拟内存。

根据你的描述,我的水晶球透露:

  • 您的代码使用/LARGEADDRESSAWARE选项编译为32位。
  • 您的代码在运行32位版本Windows的计算机上始终崩溃。
  • 您的代码有时会运行但在启动时会在运行64位Windows的计算机或使用/3GB boot.ini选项的32位Windows时崩溃。

正如Cyber​​所说,您应该构建代码以使用更少的堆栈空间。 Mats在答案中给出了一些实用的建议。

至于在运行时设置堆栈保留,是的,可以使用CreateThread的第二个参数。基本上,您将主线程保留为小堆栈(例如,默认大小),然后使用所需大小调用CreateThread并从新线程执行所有操作。但是不要这样做,而是修复你的堆栈使用率过高。