今天调试动态库的时候,有个函数在返回的时候总是要报错。在CALLSTACK窗口中看见是堆栈释放出了问题。但是我一向也是坚持谁申请谁释放不是就OK了吗。空气这函数里面还没有堆操作,全部是局部变量啊,怎么会出错呢?
经过仔细排查,最后把函数的调用方式全部改为_stdcall方式,当时还以为是不是参数出入栈问题,找不到原因就乱碰吧。但是虽然不是这里的问题,我却发现,当函数调用方式改为_stdcall方式后,调试时CALL STACK中的提示却变得清晰,不像以前那样全是难读的汇编代码,而是可以看清楚的函数调用关系。通过CALL STACK往回追踪,找到了是参数中使用了CString类型作为参数,就是他引起的问题了。
原因个人分析如下:
初看上去,CString是函数的参数,应该是一个局部变量吧,不会有问题吧。可是要清楚的是在对CString赋值的时候,它不是复制了一份,而是对原字符串增加了一个引用,到该变量生命周期结束时再解除引用。但问题是我传递给该参数的字符串是从主应用程序中,也就是说是另一个模块中。在该过程中也就间接地形成了我(主程序)申请,你(动态库)释放了。所以导致错误产生。
由于CString使用方面,很多时候都想方设法的去使用他们来完成字符串操作。用多了,就把他们当成int、char等基本类型使用了,都忘记了他们是经过加工的类了。于是问题就是常常处在这些使用最熟悉的东西身上。在此笔记一下,以吸取教训,以希望能让看到此文者不在犯这样的错。