我如何找到可用的堆栈空间的大小
How do i find out the size of available stack space?
我们都知道堆栈正在向下增长,因此,这确实是一个简单的假设,即如果我们找到 last 声明的变量的地址,我们将拿出堆栈中最小的地址,因此我们可以假设此地址将是我们的剩余可用堆栈。
我做到了,我得到了笨拙的地址{0x000000dc9354f540} = {947364623680}
我们知道堆栈向下增长,我们知道我们不能低于0。所以一点数学:
947364623680 / (1024*1024*1024) = 882.302060425
->他们是否暗示我的机器上有882GB的堆栈?
我对其进行了测试,显然在堆栈中分配了其他2MB后获得堆栈溢出例外:
uint8 array[1024*1024*2] = {};
,我的问题来了,这是我的实际堆栈大小吗?
,由于您的问题具有标签" visual-studio-debugging",我假设您使用Windows。
首先,您应该获得当前的堆栈指针。要么获取本地虚拟变量的地址(就像您现在一样(,要么通过RAW asm
读取esp/rsp
,要么获取本地虚拟变量的地址(就像您现在一样(,或通过win32 API呼叫GetThreadContext
获得CPU寄存器(。
现在,为了找出可用的堆栈大小,您可以使用VirtualQuery
查看此虚拟内存区域的起始地址(又称基础基础地址(。基本上减去这些指针会给您剩余的堆栈尺寸(精度至当前堆栈框架的大小(。
很久以前,我已经写了一篇有关此主题的文章,包括查询当前分配/保留的堆栈尺寸。如果需要,您可以在那里找到更多信息:
他们是否暗示我的机器上有882GB的堆栈?!
它与"机器上的堆栈"无关。这是关于虚拟地址空间,这与系统中可用的物理存储(RAM 页面文件(无关。
在Win32应用程序中的任何给定点留下的堆栈空间的近似值的另一种方法将是以下功能。它使用结构化的异常处理来捕获堆栈溢出异常。
注意: @Valdo的解决方案是正确的解决方案。我要发布此答案,因为这是解决问题的有趣方法。它将非常慢,因为它的运行时是线性的(根据堆栈尺寸(,而不是 @valdo的解决方案的恒定运行时。
static uint64_t GetAvailableStackSpace()
{
volatile uint8_t var;
volatile uint8_t* addr = &var;
volatile uint8_t sink;
auto filter = [](unsigned int code) -> int
{
return (code == EXCEPTION_STACK_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
};
__try
{
while (true)
{
addr = addr - 1024;
sink = *addr;
}
}
__except (filter(GetExceptionCode()))
{
return (&var - addr);
}
return 0;
}
这是@Valdo提到的VirtualQuery
技术的实现。此功能返回可用的堆栈字节数量大约。我在Windows X64上进行了测试。
static uint64_t GetAvailableStackSpace()
{
volatile uint8_t var;
MEMORY_BASIC_INFORMATION mbi;
auto virtualQuerySuccess = VirtualQuery((LPCVOID)&var, &mbi, sizeof(mbi));
if (!virtualQuerySuccess)
{
return 0;
}
return &var - mbi.AllocationBase;
}
- 如果我们通过引用传递变量,则递归中使用的堆栈空间量是否为零?
- 如何将 Boost::ASIO 与用户空间网络堆栈集成?
- 我如何找到可用的堆栈空间的大小
- 加载到阵列中会导致堆栈粉碎,同时有足够的空间
- 主堆栈空间和任务堆栈空间
- 为什么堆栈中的函数局部变量之间存在内存空间
- 线程的单独堆栈空间的重要性
- 多线程时,您该怎么做才能停止堆栈空间
- 如何使用 vc++ 找出当前线程堆栈上还剩下多少空间
- iostream 是否占用堆栈空间
- 如何在堆栈上为非默认构造对象保留空间
- c++:在堆栈空间中重复临时分配
- MPI调用需要多少堆栈空间
- 是我的堆栈内存空间膨胀
- 做了主函数和另一个函数在C++使用相同的堆栈空间
- 使用内存区域作为堆栈空间
- 堆栈空间不足错误(堆栈溢出错误)
- 在窗口中移动或指定线程堆栈空间
- 使用虚函数调用时节省堆栈空间
- 如何防止msvc++为switch语句过度分配堆栈空间?