DentistryDoctor的专栏

欢迎大家指正其中的错误

原创 递归的问题收藏

新一篇: Recommend:Visual Leak Detector (VLD) | 旧一篇: Y2038,让我提前遇上了千年虫!

  在前一段时间的项目中,我们遇到了一个问题。那就是在主程序中运行一切正常,但在Shell扩展中执行,某些极端的情况系统会崩溃,而且没有任何提示。是什么问题呢?想了很多种可能,但我想极有可能是堆栈溢出。因为主程序的堆栈如果没有修改编译选项,应该是1M;但Shell扩展实际上只是运行explorer的一个线程空间内,其堆栈应该小得多。
    最多我们找出了问题所在,因为程序需要搜集目录及文件信息,用到了递归的方式遍历整个目录树,其中传递了一个大对象作为作为参数(以引用的方式进行传递的),但我发现,在传递的过程中实际上需要生成一个临时对象,最后通过修改,避免了临时对象的产生。再运行程序,发现还是有问题,但递归层次加深了。
  看来的确是堆栈溢出。接下来,我们又发现了一个大对象产生的根源:WIN32_FIND_DATAW(因为我们是UNICODE编码),将它改成了从堆上分配。再次运行程序,发现还是有问题,但递归层次更深了。
  为什么还会溢出呢?最后发现了一个一直视而未见的大对象:
 if(error occoured)
 {
  CReportItem reportItem;
  ....
 }
  直到后来才知道,在函数中只要声明了变量,即便你不执行到相应的路径,但它一样要占堆栈空间。VC的编译器会在调用时一次性分配足够的堆栈空间.
  又将它分配在堆上,问题解决。
  可见在递归时,大对象可能带来很多问题,严重时会导致程序崩溃。同时过深的归递层次也会严重影响效率,适当的时候,我们应该改造递归算法,用循环来作为替代品。

发表于 @ 2006年02月11日 14:24:00|评论(loading...)|编辑

新一篇: Recommend:Visual Leak Detector (VLD) | 旧一篇: Y2038,让我提前遇上了千年虫!

评论

#疯子阿虹 发表于2006-08-30 20:54:00  IP: 61.49.103.*
使用循环代替地跪本来就是一种很好的优化!

这个是肯定的啊,入口的时候就已经修改esp寄存器了!!
在函数中只要声明了变量,即便你不执行到相应的路径
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © DentistryDoctor