在visual studio C++中,有没有任何方法可以在运行时增加堆栈保留大小

Is there any way to increase stack reserve size in running time in visual studio C++

本文关键字:运行时 增加 堆栈 保留 方法 studio visual C++ 有没有 任何      更新时间:2023-10-16

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

现在我有两个问题:

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

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

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

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

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

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

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

更改虚拟内存设置并不重要,因为问题在于地址空间,而不是所有进程的最大虚拟内存总量。

根据你的描述,我的水晶球显示:

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

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

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