sha*_*oth 6 c++ windows winapi visual-c++
我的Win32 C++应用程序充当RPC服务器 - 它有一组用于处理请求的函数,RPC运行时创建一个单独的线程并调用该线程中的一个函数.
在我的函数中,我有一个std :: auto_ptr,它用于控制在编译时已知的堆分配的char []数组.它在使用VC++编译时非常有效,但根据C++标准,它是未定义的行为,我想摆脱它.
我有两个选项:std :: vector或堆栈分配的数组.由于我不知道为什么有堆分配的数组,我想考虑用堆栈分配的数组替换它.该数组是10k元素,如果RPC运行时生成一个堆栈非常小的线程,我可以假设它面临堆栈溢出.
我想检测一下典型地为线程分配了多少堆栈空间,以及我的函数有多少可用(它的被调用者肯定会消耗一些分配的空间).我怎么能这样做?
如果您无法访问该CreateThread调用,或者如果它是主线程,则查看EXE在PE头中的默认线程大小,我不知道如何使用API直接计算堆栈大小.
在你的情况下,我会在堆上分配是安全的,即使10K数组的小数据不可能在非递归场景中最大化堆栈.
但是,如果仔细进行,您可以探测堆栈限制.当您触摸它们时(通过保护页面),堆栈将以4K页面提交,直到达到限制为止,Windows将引发堆栈溢出异常.调度异常时仍然有一页堆栈,因此异常调度逻辑本身(包括过滤器函数)可以执行 - 但Windows抛出异常,因为它无法分配另一个防护页面.这意味着下一个堆栈溢出或探测不会导致堆栈溢出异常,但会导致访问冲突.因此,为了使探测工作可靠(特别是可重复),您需要解除探测分配的内存并恢复保护页面.
关于KB的这篇文章介绍了如何解除堆栈内存并恢复保护页面.它使用递归和10,000字节增量进行探测; 默认情况下,编译器实现自己的堆栈探测,查找本地> 4KB的堆栈分配,以便堆栈增长机制正常工作.
我不确定你在追求什么。
如果您只想要典型的数字,那么就去尝试吧!创建一个具有嵌套作用域的函数,每个作用域分配更多的堆栈空间。每个范围内的输出。看看事情进展到什么程度。
如果您想要具体情况下的具体数字,请问问自己,一旦获得这些数字,您想做什么?分支到不同的实现?这听起来像是一个维护问题,使用它应该是非常合理的。您期望获得什么?这真的值得这么麻烦吗?
我同意 10k 通常应该不是问题。因此,如果您的代码不是关键任务,请继续使用boost::array(或者std::tr1::array,如果您的标准库附带它)。否则,只需使用std::vectoror ,如果您觉得必须的话,boost::scoped_array(或者std::tr1::scoped_array,如果您的标准库附带它)。