C++ C+的可用堆栈大小+;线
我使用Windows10,VisualStudio2019 程序生成线程。我需要添加功能,指出在任何执行时间内可用的堆栈大小C++ C+的可用堆栈大小+;线,c++,windows,winapi,stack,virtualquery,C++,Windows,Winapi,Stack,Virtualquery,我使用Windows10,VisualStudio2019 程序生成线程。我需要添加功能,指出在任何执行时间内可用的堆栈大小 #include <iostream> #include <thread> void thread_function() { //AvailableStackSize()? //Code1 //varibales on stack allocation + function call //AvailableStackS
#include <iostream>
#include <thread>
void thread_function()
{
//AvailableStackSize()?
//Code1 //varibales on stack allocation + function call
//AvailableStackSize()? it should decrease
//Code2 //varibales on stack allocation + function call
//AvailableStackSize()? it should decrease
//Code3 //varibales on stack allocation + function call
//AvailableStackSize()? it should decrease
}
int main()
{
std::thread t(&thread;_function);
std::cout << "main thread\n";
std::thread t2 = t;
t2.join();
return 0;
}
也许我还可以检查堆栈中是否有地址
PVOID add;
(add>= mbi.BaseAddress) && (add < PBYTE(mbi.BaseAddress) + mbi.RegionSize);
pvoidadd;
(add>=mbi.BaseAddress)&(add
我看到了几个类似的问题,但没有人100%回答这个问题。
获得可用堆栈大小的正确方法是什么?由于堆栈向下生长,因此它是堆栈的潜在底部和当前使用的结束之间的差异。顺便说一句,您不需要任何内联程序集,因为您知道局部变量被放置在堆栈上
__declspec(noinline) size_t AvailableStackSize()
{
// Query the accessible stack region
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(&mbi, &mbi, sizeof(mbi)));
return uintptr_t(&mbi) - uintptr_t(mbi.AllocationBase);
}
这与调用者中实际可用的略有不同,因为函数调用使用了一些(存储返回地址和任何保留的寄存器)。您需要调查最终的防护页面是出现在同一个VirtualQuery
结果中,还是出现在相邻的结果中
但这是一般的方法。这是一个链接器选项,默认为每个线程1M请参见:另请参见确定大约有多少堆栈空间可用请注意,您的评论“应该减少”是基于对堆栈如何工作的基本误解。
thread\u函数的所有局部变量将在序言中保留空间。作为调用约定的一部分,所有被调用函数将在函数退出时恢复堆栈。堆栈末尾在同一函数中的语句之间移动的唯一时间是在该函数中使用\u alloca()
时。当控件返回到执行检查的函数时,即使是被调用函数中的*_alloca()`也不会影响可用堆栈。@RbMm:更好的是,如果您不需要支持较旧的Windows版本,则必须是mbi.AllocationBase
而不是mbi.BaseAddress
@dewaffled还需要考虑您的测试函数编译器(使用优化)可以替换循环的递归。为了防止这种情况,需要一些更复杂的..比如void foo(int x){size\u t s=AvailableStackSize();DbgPrint(“%p\n”,s);if(x)foo(x-1);if(!s)u debugbreak()}
__declspec(noinline) size_t AvailableStackSize()
{
// Query the accessible stack region
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(&mbi, &mbi, sizeof(mbi)));
return uintptr_t(&mbi) - uintptr_t(mbi.AllocationBase);
}