Porque está dando erro neste codigo?

Delphi

05/11/2004

PessoALL, seguinte: depois q eu executo este codigo, ao finalizar meu aplicatiovo da erro de protecao de memoria.. Somente depois que eu executo esse codigo, se eu nao o executar, funciona perfeiamente...

segue o erro:
[b:d6b3553071] Exception EAccess Vilation in module SIGAE.EXE at 000BB4D7. Access violation at address 004BB4D7 in module ´SIGAE.exe´ read of address 00000330.[/b:d6b3553071]

Desde ja agradeco a TODOS.

Segue o codigo:
var
 cQ, cQ2, cQ3, cQ4: TIBQuery;
 Temp1, Faltas1: string;
 x: integer;
begin
 Screen.Cursor := crHourGlass;
 cQ := TIBQuery.Create(Application);
 cQ.Database := DM.IBDatabase1;
 cQ2 := TIBQuery.Create(Application);
 cQ2.Database := DM.IBDatabase1;
 cQ3 := TIBQuery.Create(Application);
 cQ3.Database := DM.IBDatabase1;
 cQ4 := TIBQuery.Create(Application);
 cQ4.Database := DM.IBDatabase1;
 
 LblStatus.Caption := ´Eliminando TODOS os boletins temporários...´;
 LblStatus.Update;
 Application.ProcessMessages;
 cQ.SQL.Clear;
 cQ.SQL.Add(´delete from notas_boletim´);
 cQ.Prepare;
 cQ.ExecSQL;
 cQ.SQL.Clear;
 cQ.SQL.Add(´set generator gen_notas_final_recno to 0´);
 cQ.Prepare;
 cQ.ExecSQL;
 
 LblStatus.Caption := ´Verificando Turma do Aluno...´;
 LblStatus.Update;
 Application.ProcessMessages;
 VerificaTurma(NomeAluno.ValueList.Strings[NomeAluno.ItemIndex]);
 
 LblStatus.Caption := ´Verificando Turma do Aluno...´;
 LblStatus.Update;
 Application.ProcessMessages;
 VerificaInteligacao;
 
{ for i := 1 to 4 do
 begin }
 cQ.SQL.Clear;
 cQ.SQL.Add(´select * from NOTAS´);
 cQ.SQL.Add(´where (COD_BOLETIM = ´ + IntToStr(CodBoletim) + ´)´);
 cQ.SQL.Add(´ and (BIMESTRE = ´ + IntToStr(1) + ´)´);
 cQ.SQL.Add(´ order by COD_DISCIPLINA, BIMESTRE´);
 cQ.Prepare;
 cQ.Open;
 
 while not cQ.EOF do
 begin
  LblStatus.Caption := ´Processando Disciplina.: ´ + cQ.FieldByName(´DESC_DISCIPLINA´).AsString;
  LblStatus.Update;
  Application.ProcessMessages;
  cQ2.SQL.Clear;
  cQ2.SQL.Add(´select * from INTERLIGAR´);
  cQ2.SQL.Add(´where (COD_TURMA = ´ + IntToStr(CodTurma) + ´)´);
  cQ2.SQL.Add(´and ( (COD_DISCIPLINA1 = ´ + cQ.FieldByName(´COD_DISCIPLINA´).AsString + ´)´);
  cQ2.SQL.Add(´  or  (COD_DISCIPLINA2 = ´ + cQ.FieldByName(´COD_DISCIPLINA´).AsString + ´) )´);
  cQ2.Prepare;
  cQ2.Open;

  if cQ2.RecordCount = 0 then // nao existe nenhuma interligacao
  begin
   cQ3.SQL.Clear;
   cQ3.SQL.Add(´select * from NOTAS´);
   cQ3.SQL.Add(´where (COD_BOLETIM = ´ + IntToStr(CodBoletim) + ´)´);
   cQ3.SQL.Add(´ and (COD_DISCIPLINA = ´ + cQ.FieldByName(´COD_DISCIPLINA´).AsString + ´)´);
   cQ3.SQL.Add(´ order by BIMESTRE asc´); // ordeno pelo bimestre ascedente.
   cQ3.Prepare;
   cQ3.Open;
   cQ3.First;
   x := 1; //defino o bimestre como sendo 1
   while not cQ3.Eof do
   begin
    Inc(x);

    Temp1 := cQ3.FieldByName(´MEDIA_FINAL´).AsString;
    Faltas1 := cQ3.FieldByName(´FALTAS´).AsString;

    if (Temp1 <> ´*´) and (Temp1 <> ´-´) then
     MF[x] := StrToFloat(Temp1)
    else
     MF[x] := 0;

    if (Faltas1 <> ´*´) and (Faltas1 <> ´-´) then
     Faltas[x] := StrToFloat(Faltas1)
    else
     Faltas[x] := 0;

    cQ3.Next;
    Application.ProcessMessages;
   end;
   cQ4.SQL.Clear;
   cQ4.SQL.Add(´select gen_id(gen_notas_boletim_recno, 1) from rdb$database´);
   cQ4.Open;
   CodNotasBoletim := cQ4.Fields[0].AsInteger;
   cQ4.SQL.Clear;
   cQ4.SQL.Add(´INSERT INTO NOTAS_BOLETIM(RECNO, COD_BOLETIM, COD_DISCIPLINA, DISCIPLINA, "1B", F1, "2B", F2, "3B", F3, "4B", F4, TOTAL_FATLAS, MEDIA_GERAL, MAX4, MA, MR, MRX6, MF)´);
   cQ4.SQL.Add(´Values (:RECNO, :COD_BOLETIM, :COD_DISCIPLINA, :DISCIPLINA, :"1B", :F1, :"2B", :F2, :"3B", :F3, :"4B", :F4, :TOTAL_FATLAS, :MEDIA_GERAL, :MAX4, :MA, :MR, :MRX6, :MF)´);
   cQ4.Params.Items[0].AsInteger := CodNotasBoletim;
   cQ4.Params.Items[1].AsInteger := CodBoletim;
   cQ4.Params.Items[2].AsInteger := -1;
   cQ4.Params.Items[3].AsString := cQ.FieldByName(´DESC_DISCIPLINA´).AsString;
   cQ4.Params.Items[4].AsString := FormatFloat(´0.0´, MF[1]);
   cQ4.Params.Items[5].AsInteger := TRunc(Faltas[1]);
   cQ4.Params.Items[6].AsString := FormatFloat(´0.0´, MF[2]);
   cQ4.Params.Items[7].AsInteger := TRunc(Faltas[2]);
   cQ4.Params.Items[8].AsString := FormatFloat(´0.0´, MF[3]);
   cQ4.Params.Items[9].AsInteger := TRunc(Faltas[3]);
   cQ4.Params.Items[10].AsString := FormatFloat(´0.0´, MF[4]);
   cQ4.Params.Items[11].AsInteger := TRunc(Faltas[4]);
   cQ4.Prepare;
   cQ4.ExecSQL;

  end;
  Application.ProcessMessages;
  cQ.Next;
 end; //fim do while do cQ
 //end; //fim do for
 
 { Libero todosos querys usados no processo}
 cQ.Free;
 cQ2.Free;
 cQ3.Free;
 cQ4.Free;
 DM.IBTransaction1.Commit;
 Screen.Cursor := crDefault;
 LblStatus.Caption := ´Reprocessamento do Boletim finalizado com SUCESSO ! ! !´;
 LblStatus.Update;
 Application.ProcessMessages;



Titanius

Titanius

Curtidas 0

Respostas

Michael

Michael

05/11/2004

Olá amigo Titanius!

O erro de violação de acesso (Access Violation) significa que o programa tentou acessar um endereço da memória inválido. Isso pode ocorrer quando se tenta usar, por exemplo, um objeto que ainda não foi criado ou então que já foi destruído.

Se você, por exemplo novamente, destruir um componente que foi criado automaticamente pelo formulário, este tentará liberá-lo quando a execução do programa terminar, e, como o objeto não existe mais: ´Access Violation´.

Você pode verificar se no evento OnClose ou OnCloseQuery do formulário em questão há alguma coisa que faça referência a algum objeto utilizado no código ou então se nesta rotina que você publicou algum objeto é destruído onde ele não deveria ser.

Qualquer dúvida, poste outra mensagem.

Abraços!


GOSTEI 0
Macario

Macario

05/11/2004

Ola programador boa tarde.

Tente ao inves de passar a aplicação como proprietario passe o form

Use isso:
[b:2a9d6a2760]cQ := TIBQuery.Create(Self); [/b:2a9d6a2760]

ao inves disso:
cQ := TIBQuery.Create(Application);

P.s. : nao manjo muito, mas creio que passando a aplicação como proprietario ao encerrala ela ira ´tentar´ destruir os objetos novamente.


Espero ter ajudado.


GOSTEI 0
Gilvanj

Gilvanj

05/11/2004

creio que passando a aplicação como proprietario ao encerrala ela ira ´tentar´ destruir os objetos novamente.


Sim, ao tentar destruir um objeto (objeto ´A´, por exemplo), todos os objetos que o tem como Owner (objetos ´B´ e ´C´, por exemplo) também são destruídos. Porém se vc destruir o objeto ´B´ antes que seja destruído ´A´, o evento Notification de A deve ser chamado informando que um objeto na qual A é proprietário está sendo destruído e que portanto, A deve deixar de dar o free em B. Se isso não está ocorrendo, deve ser um bug do componente TIBQuery.


GOSTEI 0
POSTAR