• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

nitoc3

Heap???

8 mensagens neste tópico

Estou a receber o seguinte erro de cada vez que executo a aplicação que estou a fazer:

"Debug Output: HEAP: Free Heap block 21438b8 modified at 2143ad8 after it was freed Process bbt.exe (3832)"

Se executar a aplicação sem fazer debug recebo o erro:

"Access violation at address 777722086 in module 'ntdll.dll'. Read of address 5F176793."

Alguem sabe o que isto quer dizer?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estás a aceder a uma zona de memória onde não devias... pelo erro parece que estás a libertar memória e depois a tentar aceder à mesma zona. Sem mais dados não te posso ajudar... um acesso a um objecto que já não existe, talvez...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Também não sei se consigo explicar melhor mas a aplicação acede a uma base de dados MySQL usando ADO, retira a informação de um TEdit e depois faz uma busca na base de dados pelo termo. Quando inicio o programa pela primeira vez e faço a primeira busca tudo corre bem, a busca é efectuada sem problemas e os dados são retirados da base de dados e colocados onde pretendo, o problema acontece quando efectuo uma segunda busca, ai dá-se o erro.

Sempre que o programa faz um segundo SELECT na base de dados tudo corre mal.

O código que estou a usar é este:

  procedure TMainForm.ProcLivroButtonClick(Sender: TObject);
  begin
    if (ProcLiTituloEdit.Text <> '') or (ProcLiIsbnEdit.Text <> '') or (ProcLiCotaEdit.Text <> '') or (ProcLiAutorEdit.Text <> '') or (ProcLiEditoraEdit.Text <> '') or (ProcLiTemaEdit.Text <> '') then
    begin
      ADOQuery.SQL.Clear;
      
      if (ProcLiIsbnEdit.Text <> '') then
        begin
            ADOQuery.SQL.Text := 'SELECT * FROM livros WHERE ISBN='+ProcLiIsbnEdit.Text;
            ProcLiIsbnEdit.Clear;
        end
      else if (ProcLiTituloEdit.Text <> '') then
        begin
            ADOQuery.SQL.Text :='SELECT * FROM livros WHERE Titulo LIKE "%'+ProcLiTituloEdit.Text+'%"';
            ProcLiTituloEdit.Clear;
        end
      else if (ProcLiEditoraEdit.Text <> '') then
        begin
            ADOQuery.SQL.Text := 'SELECT * FROM livros WHERE Editora LIKE "%'+ProcLiEditoraEdit.Text+'%"';
            ProcLiEditoraEdit.Clear;
        end
      else if (ProcLiTemaEdit.Text <> '') then
        begin
            ADOQuery.SQL.Text :='SELECT * FROM livros WHERE Tema LIKE "%'+ProcLiTemaEdit.Text+'%"';
            ProcLiTemaEdit.Clear;
        end
      else if (ProcLiCotaEdit.Text <> '') then
        begin
            ADOQuery.SQL.Text := 'SELECT * FROM livros WHERE Cota="'+ProcLiCotaEdit.Text+'"';
            ProcLiCotaEdit.Clear;
        end
      else if (ProcLiAutorEdit.Text <> '') then
        begin
            ADOQuery.SQL.Text := 'SELECT * FROM livros WHERE Autor LIKE "%'+ProcLiAutorEdit.Text+'%" OR Autor1 LIKE "%'+ProcLiAutorEdit.Text+'%" OR Autor2 LIKE "%'+ProcLiAutorEdit.Text+'%"';
            ProcLiAutorEdit.Clear;
        end;

      ADOQuery.Open;

      LivrosEncListBox.Items.Clear;

      while Not ADOQuery.Eof do
      begin
        LivrosEncListBox.Items.Add(ADOQuery.FieldByName('Titulo').AsString);
        ADOQuery.Next;
      end;
      
    end;
  end;

Ao principio pensei que fosse da complexidade do código mas numa outra parte do programa estou a usar uma versão muito mais simples e acontece exactamente o mesmo...

procedure TMainForm.ReqAdicionarButtonClick(Sender: TObject);
begin
  ADOQuery.SQL.Clear;
  ADOQuery.SQL.Add('SELECT * FROM livros WHERE Cota="'+ReqLivroEdit.Text+'"');
  ADOQuery.Open;

  LivrosPedidosListBox.Items.Add(ADOQuery.FieldByName('Titulo').AsString);
end;

Outra vez ao fazer a segunda query dá-me o mesmo erro de HEAP...  :wallbash:

Agora o mais estranho, numa outra parte do programa tenho o código escrito de forma igual, a primeira parte do programa onde usei a query e aqui tudo corre bem e nunca me dá erro, posso fazer quantas buscas quiser que o programa funciona sempre sem problemas.

procedure TMainForm.ProcurarLeitorButtonClick(Sender: TObject);
  begin
    if (ProcLeiNumLeitorEdit.Text <> '') or (ProcLeiNomeEdit.Text <> '') then
    begin
      if (ProcLeiNumLeitorEdit.Text <> '') then
      begin
          ADOQuery.SQL.Clear;
          ADOQuery.SQL.Add('SELECT * FROM leitores WHERE NumeroLeitor='+ProcLeiNumLeitorEdit.Text);
          ADOQuery.Open;

          ProcLeiNumLeitorEdit.Clear;
          LeitoresEncontradosListBox.Items.Clear;

          while Not ADOQuery.Eof do
          begin
            LeitoresEncontradosListBox.Items.Add(ADOQuery.FieldByName('Nome').AsString);
            ADOQuery.Next;
          end;
      end
      else
      begin
          ADOQuery.SQL.Clear;
          ADOQuery.SQL.Add('SELECT * FROM leitores WHERE Nome LIKE "%'+ProcLeiNomeEdit.Text+'%"');
          ADOQuery.Open;

          ProcLeiNomeEdit.Clear;
          LeitoresEncontradosListBox.Items.Clear;

          while Not ADOQuery.Eof do
          begin
            LeitoresEncontradosListBox.Items.Add(ADOQuery.FieldByName('Nome').AsString);
            ADOQuery.Next;
          end;
      end;
    end;
  end;

Não consigo dar com a solução para o problema e já tentei tudo o que me vem à cabeça...

Isto ficou um bocado comprido mas espero ter conseguido explicar o problema...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não tenho a certeza. Mas numa coisa reparei, abres muitas vezes o query e nunca fazes close.

Para editar o AdoQuery.SQL tens de ter a query fechada...

Não tenho a certeza que seja disso, mas de qualquer maneira é boa politica fechar os querys no fim de os utilizar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já fiz close de todas as vezes que usava a ADOQuery mas continua na mesma, o problema não é esse. desconfio que o problema tem a ver com a ADOQuery mas não consigo perceber porquê.

Em desespero tentei adicionar um ADOQuery.Create(nil); antes de usar a Query e resolveu um problema para me criar dois. Já dá para efectuar várias buscas seguidas sem problema mas de cada vez que faço uma busca uma nova ADOQuery é criada o que vai aumentando aos poucos o espaço ocupado em memória pela aplicação e depois dá-me um erro de 'Access Violation' quando fecho a aplicação. Vou de mal a pior...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Curioso, alterei o "SELECT *" para "SELECT Titulo" e parecia funcionar bem, passou de duas para quatro o número de vezes que consigo fazer uma busca  :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para esse problema e necessario fazer adoquery.free no fim de utilziar, para libertar o espaço em memoria

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora