调试应用程序时,关闭应用程序就弹出一个异常提示窗口。提示窗口的内容为“Exception EInvalidPointer in module OceanProject.exe at 00002864. Invalid pointer operation”。查看CPU,发现断点停留在系统SysReallocMem的FreeMem部分,可能是内存释放出错。但是不知道该如何定位源代码哪个部分出错了?应用程序是一个多文档窗口,子窗口为手动创建的,子窗口关闭时手动释放,而对话框为手动创建,也是对话框关闭时就手动释放。这个问题,不是随时都可以出现的,而是随机出现。请教各位大侠,该如何分析和解决?

解决方案 »

  1.   

    这种情况,可能是因为使用了其他的内存管理,最后Delphi内存管理器释放后,又做了其他的释放事件,就会导致你所说的上述情况
      

  2.   

    出现这种情况,一般是你使用了自定义动态变量,就是除了Delphi能内存自动管理的 string、wideString、动态数组、Variants及接口 以外的 动态变量。这些动态变量需要你自己进行内存释放。一般用FreeMem来释放,用GerMem来创建。Dispose释放由New创建的变量。
      

  3.   

    不过你这个很简单了,直接找指针释放的地方就可以确定出错位置。freemem
    或者dispose
    函数
      

  4.   

    楼上,说的有点道理。可是,出问题的应用程序调用new、dispose各一次,而freemem根本没用。使用new为一个记录变量分配内存,然后把它保存TList变量中。从TList读取记录变量后,就调用dispose释放。
    主要指针释放的地方是VCL的代码部分释放,自己的应用程序没用释放指针的代码。
      

  5.   

    6楼说的,弹出异常提示框后,就查看CPU,发现断点停留在系统SysReallocMem的FreeMem部分。可是还是不知道源代码中那部分调用FreeMem出了问题。
      

  6.   

    一直怀疑是不是内存出了问题,是不是什么地方释放了不存在的内存。可是,使用CheckMemv.pas添加到应用程序检查内存,发现了十个泄露的地方。可是不明白产生的日志什么意思,怎么通过它分析和定位代码出错的地方?
    请教各位大侠,在开发中都使用啥工具检查内存问题?谢谢。
      

  7.   

    if Assigned(p) then
      dispose(p) or freemem(p);
      

  8.   

    楼主,给你推荐一个错误处理控件:EurekaLog,用过之后相信你会一直用它的。安装上后注意在它的配置里面启用它,当发生错误后,它会告诉你错误出现在源代码行,以及调用顺序。
      

  9.   

    使用15楼推荐工具EurekaLog,重现了问题。通过EurekaLog的调用堆栈CallBack的相关信息,发现程序弹出异常后,程序的堆栈最上面的函数为一个串口组件ApdCommPort(对应的文件为Awuser.pas)的关闭串口的DonePortPrim,出问题的代码为释放发送缓冲区的操作(调用FreeMem函数)。后面分析程序,出现这种问题的原因可能是串口正在发送数据(串口发送数据的操作在定时器的定时中断中执行),突然人为地关闭窗口,因为在关闭窗口的操作中有关闭串口的操作,可是没有关闭定时器。
    后面,在窗口的关闭中,第一个操作就先把执行串口发送数据的操作的定时器关闭。这样,问题就不会重现。
    多谢15楼的大侠,提供的工具,还有感谢各位大侠的帮助。