我正在使用firebird 2.5服务器写入数据库文件(BD.fbd)。我的delphi XE8项目有一个数据模块(DMDados),具有:
我的数据库文件包含以下表:
我有一个表单(Otimo_AG_Form /Unit_Otimo_AG.pas)会触发其他单元(metodo_dos_deslocamentos.pas)中的过程。该过程的一些参数如下所示:
procedure p_metodo_deslocamentos(Iz_in, Ax_in : array of real; out D_out, DMM_out,AM_out, AMM_out : array of real);
该过程处于循环中。当我在调试过程中运行代码时,读取参数(Iz_in, Ax_in
)并给我结果(D_out, DMM_out,AM_out, AMM_out
)就好了。但是在end
的{{1}}中,它引发了一个异常:
项目otimização.exe引发了带有消息的异常类EAcessViolation '模块'Otimização.exe'中地址00405B67的访问冲突。读取地址00000000'
有时,异常一次出现3次。之后,该过程返回结果,但是在使用该过程3次以上之后,它只是为我提供了相同的out参数(p_metodo_deslocamentos
)值。
在D_out, DMM_out,AM_out, AMM_out
之后,代码应使用我的p_metodo_deslocamentos
和以下过程填充表portico_inicial
:ClientDataSet6
但是有时在打开数据集时,它会引发与上面相同的异常,并且在我关闭并再次运行代码之前不能再使用此p_deslocamentos_bd_portico_inicial(a_aux_AG,quantidade_de_barras_AG,D_AG,DM_AG)
。奇怪的是,当我尝试关闭表单时,在使用ClientDataSet6
之后会弹出相同的异常。
p_metodo_deslocamentos
有一个很大的代码,因此我将.pas文件放在下面的链接中:
https://www.dropbox.com/s/hjoj0t0iufopulk/Metodo_dos_deslocamentos.pas?dl=0
p_metodo_deslocamentos
使用PasMatLib库,这是链接:
https://www.dropbox.com/sh/skqpnnszniixprs/AAAyATqkfrikOHAsAkT518_Ya?dl=0
我试图恢复项目的问题,但是如果有帮助,我将所有项目留在下面的链接中: https://www.dropbox.com/sh/1chbejqa26os1p8/AABk2Xy6YIGS1RhjEyzh9tpVa?dl=0
几乎可以肯定p_metodo_deslocamentos
是问题所在,但我找不到哪里。我检查了所有数组的大小,还可以。尝试在使用完所有ClientDataSets后将其关闭,但是没有用。在调用堆栈中使用的madexcep表示该异常发生在p_metodo_deslocamentos
中,有时发生在RelocMem
中。我以为如果在使用该过程后清理内存可以解决问题,但是从理论上讲,Delphi会自己完成,而且我不知道如何手动执行。
FreeMem
代码必须在FOR中执行过程
function f_table_row_count(table : string) : integer;
begin
with DMDados do
begin
QueryConsulta.SQL.Text := 'SELECT COUNT(*) FROM ' + table;
QueryConsulta.Open;
f_table_row_count := QueryConsulta.Fields[0].AsInteger;
QueryConsulta.Close;
end;
end;
procedure p_deslocamentos_BD_portico_inicial (Portico_in,quantidade_de_barras_in : integer; D_in,D_meio_barra_in : array of real);
var
barra,I,no_j, no_k: integer;
begin
with DMDados do
begin
cdsBDPortico_Inicial.Open;//Sometimes pop ups exception access violation
cdsBDPortico_Inicial.RecNo := (portico_in * quantidade_de_barras_in) - 2;
for I := 1 to quantidade_de_barras_in do
begin
barra := DMDados.cdsBDPortico_Inicial.Fields[1].AsInteger;
QueryConsulta.SQL.Text := 'SELECT J FROM BARRAS WHERE N = ' + IntToStr(barra);
QueryConsulta.Open;
no_j := DMDados.QueryConsulta.Fields[0].AsInteger;
QueryConsulta.Close;
QueryConsulta.SQL.Text := 'SELECT K FROM BARRAS WHERE N = ' + IntToStr(barra);
QueryConsulta.Open;
no_k := QueryConsulta.Fields[0].AsInteger;
QueryConsulta.Close;
cdsBDPortico_Inicial.Edit;
cdsBDPortico_Inicial.Fields[4].AsFloat := (D_in[3*no_j -3]*1000000);
cdsBDPortico_Inicial.Fields[5].AsFloat := (D_in[3*no_j -2]*1000000);
cdsBDPortico_Inicial.Fields[6].AsFloat := (D_in[3*no_j -1]*1000000);
cdsBDPortico_Inicial.Fields[7].AsFloat := (D_in[3*no_K -3]*1000000);
cdsBDPortico_Inicial.Fields[8].AsFloat := (D_in[3*no_K -2]*1000000);
cdsBDPortico_Inicial.Fields[9].AsFloat := (D_in[3*no_K -1]*1000000);
cdsBDPortico_Inicial.Fields[10].AsFloat := (D_meio_barra_in[3*barra -3]*1000000);
cdsBDPortico_Inicial.Fields[11].AsFloat := (D_meio_barra_in[3*barra -2]*1000000);
cdsBDPortico_Inicial.Fields[12].AsFloat := (D_meio_barra_in[3*barra -1]*1000000);
if not cdsBDPortico_inicial.Eof then
cdsBDPortico_Inicial.next;
end;
cdsBDPortico_Inicial.ApplyUpdates(0);
cdsBDPortico_Inicial.Close;
end;
end;
//The procedure with problem is here
procedure TOtimo_AG_Form.Button1Click(Sender: TObject);
var
quantidade_de_barras_AG, quantidade_de_nos_AG, a_aux_AG,nportico_AG: Integer;
Iz_AG, Ax_AG,D_AG,DM_AG,AM_AG,AMM_AG : array of real;
begin
quantidade_de_barras_AG := f_table_row_count('BARRAS');
quantidade_de_nos_AG := f_table_row_count('NOS');
setlength(Iz_AG,quantidade_de_barras_AG);
setlength(Ax_AG,quantidade_de_barras_AG);
setlength(D_AG,3 * quantidade_de_nos_AG);
setlength(DM_AG,3 * quantidade_de_barras_AG);
setlength(AM_AG,6 * quantidade_de_barras_AG);
setlength(AMM_AG,3 * quantidade_de_barras_AG);
nportico_AG := DMDados.cdsConfig.Fields[0].AsInteger;
for a_aux_AG := 1 to nportico_AG do
begin
p_Iz(a_aux_AG,quantidade_de_barras_AG,Iz_AG,Ax_AG);
try
// The procedure with problem is in the metodo_dos_deslocamentos unit
metodo_dos_deslocamentos.p_metodo_deslocamentos (Iz_AG,Ax_AG,D_AG,DM_AG,AM_AG,AMM_AG);
except
//Do nothing
end; p_deslocamentos_bd_portico_inicial(a_aux_AG,quantidade_de_barras_AG,D_AG,DM_AG);
end;
end;
,并将结果提供给我,然后将其保存在数据库中。我正在为我的大学的项目这样做,所以我是delphi的初学者,并且独自编写了所有代码。谢谢你们,任何帮助都会很棒。