在C++程序中确定运行时堆栈大小

7
我希望了解在C++中是否有一种方法可以程序化地确定正在运行的程序的堆栈大小。如果有,是否还有一种方法可以在运行时程序化地确定程序正在使用多少堆内存?为了确定堆的大小,我可以通过重载newdelete运算符来看到一个潜在的方法,但我不认为这对智能指针有效。
我尝试使用以下方式实现:
int main(){
    const char STACK_BEGIN = 'A';
    //a lot of code
    register unsigned long int STACK_NOW asm("%esp");
    long long int stack_size = (reinterpret_cast<int>(&STACK_BEGIN) - STACK_NOW);
    //rest of code
}

不,实际上没有标准方法来做到这一点。但可能有特定于操作系统的系统调用来获取该信息。 - πάντα ῥεῖ
据我所记,在Windows中,堆栈页面仅在需要时才被提交。这意味着指定大堆栈的成本仅在于减少地址空间,而不是实际内存使用(直到需要为止)。无论如何,通过使用分配其缓冲区动态的标准集合,例如std::vector,您可以显著减少堆栈使用。 - Cheers and hth. - Alf
6
我认为您至少可以通过在main()例程中存储指向栈中第一个变量的全局可访问指针,然后在程序执行期间的任何时候,找到最近声明的栈变量的地址与全局指针值之间的差异来大致了解堆栈使用情况。这是一种粗略的技术,但应该至少提供关于堆栈使用情况的想法。 - Logicrat
2个回答

2
首先,堆栈是线程的属性,每个线程都有自己的堆栈。由于线程由平台提供,系统接口可能会提供或不提供该信息。
对于Linux系统,可以使用pthread_attr_getstacksize()函数获取此信息。
如果您还想获取实际地址范围,则可以从STACK_BEGIN和处理器体系结构约定中获得,即堆栈是自上而下的,即STACK_BEGIN实际上在顶部,底部大约在STACK_BEGIN-‘堆栈大小’处。
对于Windows系统,堆栈范围隐藏在GetThreadInformation(()中,请参见processhacker
编辑 根据Raymond Chen的评论,GetCurrentThreadStackLimits是Windows SDK中记录的选择。

1
当有文档记录的函数GetCurrentThreadStackLimits时,无需调用未记录的API。 - Raymond Chen

2
我大致是这样解决的:

我大致是这样解决的:

int main(){ 
    const char STACK_BEGIN = 'A'; //a lot of code 
    register unsigned long int STACK_NOW asm("%esp"); 
    long long int stack_size = (reinterpret_cast<int>(&STACK_BEGIN) - STACK_NOW); //rest of code 
}

2
你有没有想过,为什么要使用x86汇编而不是在堆栈上声明第二个char并取其地址,就像你用STACK_BEGIN一样? - Johan Boulé
这将确定在“//很多代码”之后使用的堆栈大小。不明白这如何提供可用的堆栈大小。 - Sam Ginrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接