如何检测我的程序可用的堆栈空间量?

我的Win32 C ++应用程序充当一个RPC服务器 – 它具有一组处理请求的函数,RPC运行时创build一个单独的线程并在该线程中调用我的一个函数。

在我的函数中,我有一个std :: auto_ptr用于控制编译时已知大小的堆分配char []数组。 它用VC ++编译的时候意外的工作,但根据C ++标准是未定义的行为,我想摆脱它。

我有两个select:std :: vector或一个堆栈分配的数组。 因为我不知道为什么有一个堆分配的数组,我想考虑用一个堆栈分配的数组replace它。 数组是10k个元素,如果RPC运行时产生一个非常小的线程,我可以假设地面对堆栈溢出。

我想检测多less堆栈空间典型地分配给线程和多less可用于我的function(其被调用者肯定会消耗一些分配的空间)。 我怎么能这样做?

Solutions Collecting From Web of "如何检测我的程序可用的堆栈空间量?"

我不确定你在做什么。

如果你只是想要典型的数字,然后继续尝试! 用嵌套的作用域创建一个函数,每个函数分配更多的堆栈空间。 输出在每个范围内。 看看事情到底有多远

如果你想在具体的情况下具体的数字,问问自己一旦你有他们想做什么? 分支到不同的实现? 这听起来像是一个维修问题,使用它应该是非常合理的。 你期望得到什么? 这真的值得这么麻烦吗?

我同意10k通常不应该是一个问题。 所以,如果你的代码不是任务关键的,那么继续使用boost::array (或者std::tr1::array ,如果你的std lib带有它的话)。 否则,只要使用std::vector或者如果你觉得你必须使用boost::scoped_array (或者std::tr1::scoped_array ,如果你的std lib带有它的话)。

我不知道有什么方法可以直接使用API​​来计算堆栈大小,如果您不能访问CreateThread调用,或者如果它是主线程,则查看PE头中的EXE默认线程大小。

在你的情况下,即使一个10K的小数据数组不可能在非递归场景下最大化堆栈,我也会在堆上进行分配以保证安全。

但是,如果仔细进行,您可以探测堆栈限制。 当您触碰它们(通过警卫页面 )时,堆栈会以4K页面提交,直到达到限制,Windows将抛出堆栈溢出异常。 当发送异常时,仍然有一页堆栈遗留下来,这样异常调度逻辑本身(包括过滤器函数)就可以执行 – 但是Windows会抛出异常, 因为它不能分配另一个守卫页面 。 这意味着下一个堆栈溢出或探测将不会导致堆栈溢出异常,而是访问冲突 。 因此,要使探测工作可靠(特别是可重复),您需要取消探测所分配的内存,并恢复保护页面。

KB上的这篇文章介绍了如何解除堆栈内存并恢复防护页。 它使用递归和10,000字节的增量进行探测; 编译器默认实现了自己的堆栈探测,对本地的堆栈分配大于4KB,这样栈的增长机制就能正常工作。

在Windows中,默认的堆栈大小是1MB,所以你不可能只用10k的数组进行堆栈溢出。 也就是说,我认为在堆栈上分配这么多的内存是一个不好的做法,如果可以的话,你应该尝试动态分配它。 还有一个为自动管理数组定义的范围数组 – 不像vector类,它是不可复制的。

我第二次1800信息:

  • 如果可以,请在堆上分配数据。 这样更安全(例如,缓冲区溢出很难被利用),并且在以后需要扩展你的设计(而不是如果)时更加灵活。

  • 使用std :: vector,boost :: scoped_array或boost :: shared_array。

我知道这不是在检测堆栈大小时回答您的问题,但我认为这是您的问题的合乎逻辑的答案。

“std :: auto_ptr是用来控制堆分配的char [] …它是未定义的行为根据C ++”

这是错误的假设! STL的auto_ptr具有精确的行为描述。 如果您担心在复杂的分配审查期间失去控制权,可能使用引用计数器模式来控制销毁堆分配数组。