最荒唐的错误----很可能是delphi的bug?(50分)

  • 主题发起人 主题发起人 linuxping
  • 开始时间 开始时间
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
下面是出错的地方:
function TProbabilityCutWord.GetTempWord(S: AnsiString): Integer;
var
i,j,k,KK,iLen,iOffset:Integer;
sPart:AnsiString;
nd1,nd:TCharTreeNode;
wFreq:Word;
ls:TList;
begin
ls:=TList.Create;
K:=0;
i:=1;
while (S<>'') do
begin
j:=0;
nd:=nil;
repeat
SPart:=Copy(S,j*2+1,2); //依次取一个字
nd1:=nd; //保存上一次的值
nd:=FDict.FindCharacter(SPart,nd);
Inc(j,1);
until ((nd=nil) or (j*2+2>Length(S))) ; //直到没有匹配到 或 字串取完 为止

if (j*2+2>Length(S)) and (nd<>nil) then //字串取完了
FDict.TraceAll(nd,ls)
else if (nd1<>nil) then //没有匹配到,向后回溯
FDict.TraceAll(nd1,ls)
else raise Exception.CreateFmt(StrCharsetEncodingError,[SPart]);

Delete(S,1,SysUtils.CharLength(S,1));

if ls.Count=0 then
begin
FWordInSentence[K].iOffset:=i;
FWordInSentence[K].iLength:=2;
//FWordInSentence[K].dFee:=-ln(1 / (MaxWordCount)); //<--------A处
FWordInSentence[K].dSumFee:=0.0;
Inc(K);
end
else
for KK:=0 to ls.Count-1 do
begin
if (PFreqAndWord(ls.Items[KK]).sWord<>'') then
begin
FWordInSentence[K].iOffset:=i;
FWordInSentence[K].iLength:=Length(PFreqAndWord(ls.Items[KK]).sWord);
wFreq:=PFreqAndWord(ls.Items[KK]).iFreq;
//FWordInSentence[K].dFee:=-ln((wFreq+1) / (MaxWordCount)); //< ----------B处
FWordInSentence[K].dSumFee:=0.0;
Inc(k);
end;
end;

Inc(i,2);
end;
ls.free;
Result:=K-1;
end;
一些说明:
TProbabilityCutWord是TInterfacedCutWord的子类.
FDict是TInterfacedCutWord的一私有对象.
FindCharacter是FDict的公有方法(该方法中没有任何地方释放了FDict).
FWordInSentence是TProbabilityCutWord的一私有对象(其实是一结构体,主要作用是存放字串----字串的起点,长度等).

本人多次单步执行该函数,都有以下结果:
第一遍单步执行完While循环不会报错,但第2遍单步执行while循环的时候在nd:=FDict.FindCharacter(SPart,nd)处报错,弹出-个内存存取违规的异常.

我估计是某个地方释放掉了FDict,于是我跟踪nd:=FDict.FindCharacter(SPart,nd)下面的语句,直到执行到 A处 或 B处,FDict就显示为'Inaccessible Value'(这之前会显示出FDict类的一些私有数据)

如果注释掉'A处'和'B处',却不会报错~

FWordInSentence和nd:=FDict.FindCharacter(SPart,nd)两行没有任何关系?
 
除数为0?

代码有点乱, 建议把该方法分割一下。 我看你的S 变量好像发生了变化, 怎么传入的??
 
s是转值传入~
错误不是出现在FWordInSentence[K].dFee:=-ln((wFreq+1) / (MaxWordCount));
而是在nd:=FDict.FindCharacter(SPart,nd);
不是除数为0?
 
看你的代码,肯定会有报错:
S一直去掉第一个字符,当S的长度为1时,SPart:=Copy(S,j*2+1,2);就会越界,就是内存访问异常了
 
串在赋值给S这之前已经被过滤,串S中只有汉字!!!!!
再说出错的地方不在这一行~而在nd:=FDict.FindCharacter(SPart,nd);
 
很奇怪:
我将FWordInSentence从类TProbabilityCutWord的私有域中移出,改为全局公有(整个Pas单元公有),错误不见了....但不明白道理..
 
这个问题还真有意思
 
问题已经找到:
原因是 我在定义FWordInSentence数组时下界是1,而在使用的时候,却用了:FWordInSentence[0].....KK会等于0..
我的解释:
大概编译器是将私有变量'并排'放在一起,于是FWordInSentence[0]篡改了同样是私有变量(不过是基类私有)的FDict.....因此,错误反而出现在nd:=FDict.FindCharacter(SPart,nd);而不出现在真正产生错误的地方FWordInSentence[KK].XXXX
 
感谢大家的参与~~~
发分~~~呵呵~
 
接受答案了.
 
不好意思~~发错分了~本来是想给 duhai_lee 15分,qizhao_2001 35分的
 
后退
顶部