闲人草堂

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

程序运行中,最诡异的就是内存问题了。(限于个人经验问题,暂时只碰到这个程度的,如果还有诡异程度更甚的,请告诉我)内存问题仿佛天外流星,不知其何时来,不知其症状如何,飘忽不定,直到程序崩溃为止。

今天就碰到了一例。

void fun()
{
   vector<double> v1;
   vector<double> v2;

   process();
   ........
}

在某个函数体内,申明了v1,和v2两个vector,然后balabala,直到要退出fun的作用域,析构v1的时候,程序崩溃。

尝试着把v1,v2的申明顺序换了一下,症状变了,在析构v2的时候出错;接着尝试,把v1,v2设为static变量,发现这会不报错,但是出了fun函数之后,在其他函数体内又出现类似的问题。

至此,基本可以下结论了。这是一起典型的内存问题,可能是数组访问越界,可能是内存泄露等等。

你想问,为什么可以下这个结论?我们可以来分析一下:

首先,并不是v1,或者v2的析构出错;而是第一个申明的变量析构出问题。这给了你什么启发?在函数体内申明的变量(非static,也不是用new申请的内存空间),都属于局部变量,程序统一用栈来管理。申明的时候一个个push进栈,退出作用域的时候,一个个pop出栈,调用变量自身的析构函数。当pop到最后一个的时候出错,说明栈已经被弄乱了,无法根据地址正确的调用该变量的析构函数。

为什么用static变量就不报错呢,很简单,static是全局的,不会在退出函数作用域的时候被析构。

接下来,使用二分法定位,发现问题就在process()这个函数体内了。可是这个函数体有数百行,该怎么查呢。

这时候只能用valgrind来帮忙了(没听过valgrind的同学自己google吧)。终于发现了一处数组访问越界,我了个去,忙活了大半天就是为了这个错误……

问题是解决了,但是该怎么办才能保证以后类似的问题不发生呢?

c++并不会检查数组访问是否越界,那我们该怎么做呢。

一个想法是,对于自定义的数据结构,重载(),对于下标运算,先assert一下,看看下标有没有越界,但是对于内建的数组,或者stl容器,我就不知道有什么办法可以在编译时检查,或者在运行出错的时候能够给出一个明确的错误信息。

如果有人对于这方面有啥心得体会,请不吝赐教!

posted on 2011-08-05 14:30  闲人草堂  阅读(378)  评论(0编辑  收藏  举报