致命错误C0000005

lj_lt 2007-07-15 09:41:56
希望这段在网上找到的文章 , 对你有点帮助 ...

c0000005错误发生的诱因主要分为四大类:

1、自由表存储载体的缺陷(主要体现在VCX、VCT,SCX和SCT上)。
2、第三方监控性质的软件(如:防毒软件在内存实时监控状态下、词霸在全屏拾取模式下等);
3、Visual Foxpro 自身的代码漏洞;
4、硬件因素。

先说第一大类:

同数据表一样,在Visual Foxro 9.0 版本中,自由表也支持了原子事务机制,这幷非主要是为了满足客户的需要,而以稳定VFP9自身为主。我们都知道类与窗体的代码多以物理形式为自由表的VCX、VCT,SCX和SCT文件格式存储,在IDE设计模式下,代码被VFP后台以独占的、开放式自由表缓冲的模式存取。然而您应该敏感地注意到:自由表是不支持事务机制的(低于9.0版本的Visual Foxro)。也就是说,遇到停电或操作系统异常时,它们同样会面临表头损坏、低级链接错误、记录指针错误偏移的风险。Microsoft Visual Foxpro 開發組沒有將VCX、SCX設計爲依賴于數據庫的數據表的形式,原因不難理解——如果一個表單文件中,包括表單本身在內的任何一個控件都不依賴于用戶自定義派生類的話,那該文件應該可以被獨立地拷貝與打開。

如下的常识我们都需要知道:

无论是在设计模式还是在运行模式下,Visual Foxpro的Runtime会随时将客户本读取到内存体中,幷交由词法分析器、语法分析器和语义分析器来分析、解释、处理这些代码。

(通常情,在编辑模式下,我们的本代码已经被Visual Foxpro词法分析器进行了第一遍的过滤;在编辑完一个prg或窗体或类文件后,若按下Ctrl+W组合键将在保存它之前调用语法分析器来试图检查其中的错误(注意“词法”分析器与“语法”分析器的不同),然后程序界面将自动被关闭;而若按下Ctrl+S组合键保存后,再手动退出时,这种情下将不会调用语法分析程序。)

如果你的本保存在自由表形式的SCX、SCT、VCX、VCT文件中,Visual Foxpro会通过表的记录指针提取对应备注文件里的程序本(那里或许包含了某些事件或方法的代码)。首先,Visual Foxpro 的底层通过调用C语言的sizeof()来判断字节的长度,根据长度提取字节,将其存放到字符类型的数组中,最后将长度的返回值与该存放实际代码的数组以参数的形式传递给语义分析器来解释执行。然而在一些情下,会发生sizeof()判断的字节长度与实际的长度不一致的情。

倘若sizeof()判断的字节长度与实际的长度不一致,将会发生内存的溢出,这个致命错误被Visual Foxpro异常处理器捕获后,将抛出“致命错误-C0000005”的信息。

“致命错误=”是字符常量,“c0000005”是一个变量,c0000005不是VFP的错误编码,而是得到Windows消息环所传递过来的错误消息参数的半加工品。它的原始状态是16进制的0xC0000005,VFP通过相关的转换函数转换成字符串的形式,以便通过界面描述给用户。

那什情下會出現sizeof()判斷的字節長度與實際的長度不一致的情呢?主要有两方面的主导因素。

1、我们前面铺垫过了,VCX、VCT,SCX和SCT文件都是自由表,都有可能在设计时被无意的损坏。

倘若表头被损坏,您会在试图打开它们的时候收到VFP系统的无法打开该窗体的信息;但倘若低级链接错误、记录指针错误偏移,您就不会得到任何VFP的提示,因为VFP系统自己也不知道这一点,就像您一样。于是直到程序运行时,才会收到令人惊愕的致命错误信息——语义分析器工作时内存被溢出。

在一些“致命错误-C0000005”的信息框中,您会收到似乎更详细些的信息,指示您程序出错的地方。那通常是包含在SCX、SCT或VCX、VCT里某些行的代码。

千万不要被误导,幷不是您的程序代码编写有问题,而是隐藏在标识符之外的、看起来好像是空格、回车的空白段,那里隐藏了低级链接的错误、或Unicode的错位排序(下面马上就会讲述到),用Shift+箭头键将整行全选,然后按Delete键除之,最后老老实实地将原行代码重新书写一遍即可(切记:用Shift+箭头键将整行全选,然后将该整行彻底清除)。

2、Unicode

从Windows98升级过来的VFP程序员似乎都曾有过这样的困惑:爲什Windows2000以上版本的VFP程序會如此的不穩定,以至于頻繁出現“致命錯誤——C0000005”?

Visual Foxpro的词法扫描仪大概是这样工作的:词法扫描仪分析代码本的时候,先要判断一下 下一个被扫描的Token是否为空标记。若是,则看该空标记是Tab标记还是回车标记,或者是分隔符或其它的占位符;若不是,则判断该Token是单字节还是双字节字符,这种机制在基于Unicode的Windows版本中,有时会遇到标识符号的错位。

您现在上网用的计算器的操作系统是WIN2000或WinXP吗?如果是,不妨亲自做这样一个试验:

打開記事本程序,輸入“聯通”,然後保存後關閉該文本,再重新開打,看到什了?标识符号被错位了!

是的,当年WIN2000操作系统的流行时,Visual Foxpro开发组幷没有彻底改正语义分析器代码的漏洞。
好的,第一大类我就阐述完了。如何避免它呢?

总的应该说很麻烦,有两种途径供您选择:

1、修改VCX、SCX表国际代码页的编码,将简体中文编码改为英文编码;

2、我所推荐的方法是尽量用prg。你可能会认为这样做很麻烦,但作为程序员,您应该更加专业一些。您可以备份可视化的窗体或类文件,但在程序正式发布前,最好最大限度地转化为prg程序。倘若以后需要修改程序,通过备份的窗体或类文件进行可视化编辑,然后再次转化为prg发布之。

对于已经开发好的项目,就没有必要大兴土木地全部将Vcx、Scx转化为Prg了,但您应该着重关注一下主菜单Mnx文件,及控件(尤其是图片)特别多的窗体。或许,您曾遇到过这样令人匪夷所思的问题:在運行exe文件時,爲什有時候一切正常,而有時候産生致命异常——要知道開發人員根本就沒改任何的代碼呀?


...全文
3001 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
Foxer 2007-07-16
  • 打赏
  • 举报
回复
绝大多数的原因是双字节字符(汉字)的问题,尽量不要用LEFTC()、SUBSTRC()这些函数,就会减少大多数的C5错误
lj_lt 2007-07-15
  • 打赏
  • 举报
回复
下面我将剖析上面的问题:

在用菜单编辑器进行菜单定义时,Visual Foxpro系统将产生四个对应文件:一个自由表、前者的备注文件,一个程序文件(mpr)及它的执行格式文件(mpx)。

如果您用 Do Menu XXX.mnx 的方式调用主菜单时,.mnx与.mnt两文件将被包含至工程中去,在exe执行时,以提取自由表记录的形式解释程序。

但mnx模式存在着一个致命的缺欠,就是Visual Foxpro 在申请堆栈时的预定空间量相对prg的程序文件要小许多。通常這沒什問題,但你要知道幷不是每次Visual Foxpro 都能如願地向Windows操作系統申請到預定的空間值,有的時候它所獲得的堆棧數目會少一些,甚至恰巧會小于菜單初始化時所需要占用的空間量。這就是爲什有時候exe第一次運行時正常,退出後再次運行時偶爾會出現“致命錯誤-c0000005”的原因。

请您以 Do XXX.mpr 的形式直接调用程序文件形式的mpr,就能很好地避免之。因为在默认情下,Visual Foxpro 为程序文件所申请的堆栈数远远大于mnx,即便是Visual Foxpro没有从Windows操作系统中得到预定数目的空间,然而比起 定义存储prg内本的字符型数组的长度来说,也绰绰有余了。

另外,一个存储了大量控件与图片信息的窗体,同样会遇到与菜单文件相似的情形——即Visual Foxpro 所获得的堆栈数小于窗体初始化时所需要的数目,从而造成内存的溢出。

顺便告诉您一个小窍门:

在IDE设计模式下,我们或许会突然遇到“致命错误-C0000005”袭击,因为窗体是以独占的、开放式自由表缓冲的模式交互的,所以此前未经保存的信息都将被丢失,这您是知道的,通过刚才的讲述,您还知道了这或许会面临表被损坏的风险,从而进入了一个“致命错误-C0000005”在引发今后“致命错误-C0000005”故障的恶性循环。

小窍门就是,您千万不要条件反射地去触击那个“确定”按钮!那不过只是Visual Foxpro系统所捕获的异常罢了,它不是真“致命”的,Visual Foxpro系统仍在运转中,也就是说,它还在正常地接收着Windows操作系统不断发送来的消息。这时,请您点开Windows桌面最左下角的“开始”按钮,选择“重新动计算器”或“关闭计算器”,Windows在试图关闭计算机前,会先检查是否有尚在运行中的应用程序,它会发现一个叫Fox的先生尚未退场,于是便发送清场的消息给Foxpro,Visual Foxpro其实还在正常的运转中,它接收到这条消息后,会调用自身的退出机制试图退出,而自身的退出机制会发现尚有正在编辑的窗体,便会发出“需要保存修改吗?”的询问消息,这时候,您选择保存,就可以了!

千万注意了!这段过程大概只有5秒钟的时间!因为为了防止死循环的情出现,Windows会在等待几秒钟对方不应答的情下行终止程序,那时候,就真正退出整个Windows系统了。所以您一定要眼疾手快!

第二大类是第三方监控性质的软件。如:防毒软件在内存实时监控状态下、词霸软件在全屏拾取模式下等。其实防毒软件本身幷不与VFP产生冲突,但有一个例外,就是内存实时监控(请注意:防毒有许多实时监控,唯有内存实时监控才会与有时候与VFP发生冲突)。

所謂內存即時監控幷不是去讀取內存條中的數據,誰也沒這大的本事,它的原理就是專門關注于Windows系統目錄下的system32子目錄中的程序文件在運行中的狀態。

我们知道,在Visual Foxpro 8.0 版本以前,其运行时刻文件是安装在system32目录中的;而向最終客戶發布你的應用程序時,默認情下,無論是VFP什版本,其運行時刻文件均會被拷貝到system32目錄中去。

防毒软件的内存实时监控的工作原理是这样的(这是瑞星公司首创的,瑞星软件也是狐友受害最深的):1、它会在Windows后台运行一个类似于Windows的模拟机(这有点像任天堂游戏模拟机和一些手机模拟机,还有现在时髦的Linux下的Windows模拟机);2、它运行一个循环,挨个监视system32目录下的exe及dll文件是否被调用;3、倘若被调用,就拷贝一份到瑞星自己创建的隐含、系统目录中去,然后在那个模拟机中运行之,以便模拟其在Windows实际运行中的状态;4、在模拟运行中,看它是否有病毒发作的特征;5、如果有,就查找病毒特征码数据库;6、若在數據庫中,找到了對應的特徵碼,便確定特徵碼所對應的病毒名稱,否則,就按未知名的新病毒處理(這就是爲什有的VFP加密軟件會被防毒軟件誤報病毒)。

由于VFP应用程序与运行时刻DLL库交互的太频繁了,使防毒软件的那个循环程序不断捕捉到VFP运行时刻库在进行新的数据响应,防毒软件便不断地试图拷贝它,以便进行新一轮的模拟。但你知道,无论是DBF还是SCX等等,只要是独占方式打开的(SCX与VCX总是被独占的,而DBF取于你的设计),就不能被其它的程序所访问。但在Windows操作系统中,防毒软件所调用拷贝程序的系统优先级要高于你的程序的优先级,所以有时你的VFP程序会最终产生致命错误。

如何避免呢?你可以简单地关闭防毒软件,但如果让客户也像你这样做的话,就有霸道之嫌了。

聪明的你恐怕现在已经想到了:只要在发布你的应用程序时,将那些运行时刻库放到应用程序目录下就可以了!

同样,词霸软件本身也不会与你的程序发生冲突,只是在全屏取词的模式下才会如此。不过你的用户几乎不会遇到,因为你的程序几乎不会让他们在程序界面状态下直接打开某个数据表——仅在词霸的全屏取词程序试图通过独占模式下的数据表的窗口句柄,来访问里面的文本属性时,才会与其独占模式发生冲突。

第三大类是Visual Foxpro 自身的代码漏洞。比如VFP6.0版本的Textbox控件等等。现在版本的VFP,这样的错误少多了。关于Visual Foxpro 自身的代码漏洞导致c0000005异常的话题,早已被论坛上诸多的高手反复总结过了,我们的话题就不再展开了。

第四大类是硬件因素。

有些细节问题是最不被人所注意的。但其足以铸成大过。

“致命错误C0000005”是内存泄漏的症状,而不仅仅是内存溢出、除零(这就是Visual Foxpro 自身的代码Bug所导致的结果),还有一个原因就是申请到的堆栈意外不足。

在用电高峰期(例如夏季、或晚间的黄金时段),电压的突然不稳定,或许会非常微小,不至于迫使计算器意外重,但或许会导致VFP系统在通过Windows消息机制向内存体申请堆栈时,得到Windows意外的反馈。

除了说服您的客户使用UPS外,您应该检查用电的负荷情,比如检查打印机或台灯是否与计算器电源一起接在一个多功能插座上,应该尽量避免这样,一些老式的打印机,在打印作业时会消耗很大的电流。

2,723

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧