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)两行没有任何关系?
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)两行没有任何关系?