如何解决地址00405B67上的Acess违规问题?

时间:2019-05-11 20:11:55

标签: delphi firebird2.5 delphi-xe8

我正在使用firebird 2.5服务器写入数据库文件(BD.fbd)。我的delphi XE8项目有一个数据模块(DMDados),具有:

  • SQLConnection(conexao)
  • TSQLQUery1(QueryConfig)+ TDataSetProvider1(DSP_Config)+ TClientDataSet1(cdsConfig)
  • TSQLQUery2(QueryBDVigas)+ TDataSetProvider2(DSP_BDVigas)+ TClientDataSet2(cdsBDVigas)
  • TSQLQUery3(QueryBDPilares)+ TDataSetProvider3(DSP_BDPilares)+ TClientDataSet3(cdsBDPilares)
  • TSQLQUery4(QueryBDNos)+ TDataSetProvider4(DSP_BDNos)+ TClientDataSet4(cdsBDNos)
  • TSQLQUery5(QueryBDBarras)+ TDataSetProvider5(DSP_BDBarras)+ TClientDataSet5(cdsBDBarras)
  • TSQLQUery6(QueryBDPortico_Inicial)+ TDataSetProvider6(DSP_BDPortico_Inicial)+ TClientDataSet6(cdsBDPortico_Inicial)
  • TSQLQUery7(QueryBDCarregamento_no)+ TDataSetProvider7(DSP_BDCarregamento_no)+ TClientDataSet7(cdsBDCarregamento_no)
  • TSQLQUery8(QueryBDCarregamento_barra)+ TDataSetProvider8(DSP_BDCarregamento_barra)+ TClientDataSet8(cdsBDCarregamento_bara)
  • TSQLQUery9(QueryConsulta)(仅用于使用SQL字符串)

我的数据库文件包含以下表:

  1. CONFIG(TClientDataSet1)(已填充)
  2. VIGAS(TClientDataSet2)(已填充)
  3. PILARES(TClientDataSet3)(已填充)
  4. NOS(TClientDataSet4)(已填充)
  5. BARRAS(TClientDataSet5)(已填充)
  6. PORTICO_INICIAL(TClientDataSet6)(部分填充,必须使用代码完成)
  7. CARREGAMENTO_NO(TClientDataSet7)(已填充)
  8. CARREGAMENTO_BARRA(TClientDataSet8)(已填充)

我有一个表单(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_inicialClientDataSet6 但是有时在打开数据集时,它会引发与上面相同的异常,并且在我关闭并再次运行代码之前不能再使用此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的初学者,并且独自编写了所有代码。谢谢你们,任何帮助都会很棒。

0 个答案:

没有答案