Fórum Problema ao atribuir a variaveis objetos instanciados #336082
12/01/2007
0
Preciso dar um free num componente que está numa form, e atribuir à ele um outro objeto do mesmo tipo que foi instanciado manualmente.
O seguinte teste não deu certo: suponhamos que eu tenho um componente A na form instanciado, que nada mais é que uma variável do tipo A que aponta para esse objeto. E tenho um Componente do mesmo tipo chamado B e referenciado por B. Quero trocar, quero que A (referencia ou variavel) aponte pra B, e B continue apontando pra B, para que o objeto a possa ser liberado da memoria. Pra isso eu uso uma variavel não instanciada do mesmo tipo chamada C.
Se eu faço C:=A;
A:=B;
C.free;
O que deveria acontecer? A apontando pra B, sendo A e B a mesma coisa e o objeto instanciado na memoria A não existir mais, sendo C = nil;
Não é isso que está acontecendo, por favor, alguém poderia olhar meu código?
Obrigado!
O seguinte teste não deu certo: suponhamos que eu tenho um componente A na form instanciado, que nada mais é que uma variável do tipo A que aponta para esse objeto. E tenho um Componente do mesmo tipo chamado B e referenciado por B. Quero trocar, quero que A (referencia ou variavel) aponte pra B, e B continue apontando pra B, para que o objeto a possa ser liberado da memoria. Pra isso eu uso uma variavel não instanciada do mesmo tipo chamada C.
Se eu faço C:=A;
A:=B;
C.free;
O que deveria acontecer? A apontando pra B, sendo A e B a mesma coisa e o objeto instanciado na memoria A não existir mais, sendo C = nil;
Não é isso que está acontecendo, por favor, alguém poderia olhar meu código?
procedure TForm1.Button1Click(Sender: TObject);
var
dummyEdit: Tedit;
begin
dummyEdit := Edit1;
Edit1 := Edit2;
{Mostra os nomes e conteudos dos edits. Nesse ponto, o dummy aponta para o
edit1, ele É o edit 1 (o objeto instanciado), enquanto que o edit1
(variavel) aponta para o objeto edit 2, ele É o edit 2}
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text);
ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text);
ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text);
{porque diabos essa linha abaixo não funciona direito? ela está liberando da
memoriao edit 1, que está sendo apontado pelo dummyedit, mas a variavel edit1
perde sua referencia ao edit 2 e volta a apontar para o edit1,
que já foi dado free}
dummyEdit.Free;
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text);
//A linha abaixo dá access violation, prque o edit1 não aponta mais para o edit2?
ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text);
ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text);
Edit1 := Edit2;
{Se eu fizer a referencia novamente, ele funciona como eu quero}
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text);
ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text);
ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text);
end;Obrigado!
Vitor Rubio
Curtir tópico
+ 0
Responder
Posts
12/01/2007
Emerson Nascimento
quando você faz dummyEdit.Free você está liberando na verdade o Edit1 (pois o dummyEdit é o próprio objeto Edit1).
O Edit1 não aponta mais para o Edit2, porque o Edit1 não existe mais! Ele foi
apagado da memória pelo comando dummyEdit.Free, portando ele não aponta mais
para lugar nenhum
é óbvio! é o mesmo que você fez com o dummyEdit. tente exibir
algo do dummyEdit antes do comando dummyEdit := Edit1;
não funcionaria porque dummyEdit não existiria na memória;
ele passa a existir quando você o aponta para Edit1, da mesma
forma que o Edit1 - depois de apagado - passa a existir
novamente depois que você o aponta para Edit2
procedure TForm1.Button1Click(Sender: TObject);
var
dummyEdit: Tedit;
begin
dummyEdit := Edit1;
Edit1 := Edit2;
{Mostra os nomes e conteudos dos edits. Nesse ponto, o dummy aponta para o
edit1, ele É o edit 1 (o objeto instanciado), enquanto que o edit1
(variavel) aponta para o objeto edit 2, ele É o edit 2}
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text);
ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text);
ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text);
{porque diabos essa linha abaixo não funciona direito? ela está liberando da
memoriao edit 1, que está sendo apontado pelo dummyedit, mas a variavel edit1
perde sua referencia ao edit 2 e volta a apontar para o edit1,
que já foi dado free}
dummyEdit.Free;
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text);
// A linha abaixo dá access violation, prque o edit1 não aponta mais para o edit2?
apagado da memória pelo comando dummyEdit.Free, portando ele não aponta mais
para lugar nenhum
ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text);
ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text);
Edit1 := Edit2;
{Se eu fizer a referencia novamente, ele funciona como eu quero}
algo do dummyEdit antes do comando dummyEdit := Edit1;
não funcionaria porque dummyEdit não existiria na memória;
ele passa a existir quando você o aponta para Edit1, da mesma
forma que o Edit1 - depois de apagado - passa a existir
novamente depois que você o aponta para Edit2
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text); ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text); ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text); end;
Responder
Gostei + 0
12/01/2007
Vitor Rubio
So que, por exemplo, o Objeto Edit1 não é algo diferente da variável Edit1?
Se eu tenho edit1 e edit2 na minha form, lá em cima, antes do private eu tenho as variaveis edit1, que aponta para o objeto instanciado edit1 e o edit2, que aponta para o edit2 respectivamente.
A variavel edit1 não poderia apontar para qualquer outro edit instanciado que não fosse o edit1? Na teoria sim. Foi isso que eu tentei fazer, atribuir o ponteiro do edit2 ao edit1, só que se eu fizesse isso, o objeto instanciado na memoria edit1 ficaria perdido sem quem o liberasse.
por isso e criei a variavel dummy, para apontar para o mesmo edit que o edit1, para que quando o edit1 passasse a apontar para o edit2, eu pudesse limpar o edit1 da memoria usando a variavel dummy.
Não deu certo. Com outras classes que não fossem componentes daria certo... Ao liberar o dummy, a variavel edit1 para de apontar para o edit2 como estava antes e começa a apontar para o nada, como se ainda quisesse apontar para o edit1 que foi liberado.
Olha essa parte do código depois de dar dummy.free:
Eu liberei dummy, então deveria dar access violation, mas não deu.
Olha esse outro código, que faz a mesmissima coisa que o anterior, mas usando uma outra classe que não seja componente:
Se eu tenho edit1 e edit2 na minha form, lá em cima, antes do private eu tenho as variaveis edit1, que aponta para o objeto instanciado edit1 e o edit2, que aponta para o edit2 respectivamente.
A variavel edit1 não poderia apontar para qualquer outro edit instanciado que não fosse o edit1? Na teoria sim. Foi isso que eu tentei fazer, atribuir o ponteiro do edit2 ao edit1, só que se eu fizesse isso, o objeto instanciado na memoria edit1 ficaria perdido sem quem o liberasse.
por isso e criei a variavel dummy, para apontar para o mesmo edit que o edit1, para que quando o edit1 passasse a apontar para o edit2, eu pudesse limpar o edit1 da memoria usando a variavel dummy.
Não deu certo. Com outras classes que não fossem componentes daria certo... Ao liberar o dummy, a variavel edit1 para de apontar para o edit2 como estava antes e começa a apontar para o nada, como se ainda quisesse apontar para o edit1 que foi liberado.
Olha essa parte do código depois de dar dummy.free:
ShowMessage(´Nome: ´ + dummyEdit.Name + ´ Conteudo: ´ + dummyEdit.Text); //não deveria permitir, já que eu liberei dummy, devia dar access violation ShowMessage(´Nome: ´ + Edit1.Name + ´ Conteudo: ´ + Edit1.Text); ShowMessage(´Nome: ´ + Edit2.Name + ´ Conteudo: ´ + Edit2.Text);
Eu liberei dummy, então deveria dar access violation, mas não deu.
Olha esse outro código, que faz a mesmissima coisa que o anterior, mas usando uma outra classe que não seja componente:
Tmensagem = class public mensagem: string; destructor destroy; override; end; destructor Tmensagem.destroy; begin mensagem := ´´; inherited; end; procedure TForm1.Button2Click(Sender: TObject); var mensagem1, mensagem2, mensagemdummy: Tmensagem; begin //criando os objetos mensagem1 := Tmensagem.Create; mensagem2 := Tmensagem.Create; mensagem1.mensagem := ´Aqui jaz Mensagem 1´; mensagem2.mensagem := ´Aqui jaz Mensagem 2´; ShowMessage(´Logo depois de criar:´); //ShowMessage(´MensagemDummy: ´ + mensagemdummy.mensagem); //essa não pode, obvio ShowMessage(´Mensagem 1: ´ + mensagem1.mensagem); ShowMessage(´Mensagem 2: ´ + mensagem2.mensagem); mensagemdummy := mensagem1; mensagem1 := mensagem2; ShowMessage(´Assim que atribuir:´); ShowMessage(´MensagemDummy: ´ + mensagemdummy.mensagem); ShowMessage(´Mensagem 1: ´ + mensagem1.mensagem); ShowMessage(´Mensagem 2: ´ + mensagem2.mensagem); mensagemdummy.Free; ShowMessage(´Depois de liberar dummy´); //ShowMessage(´MensagemDummy: ´ + mensagemdummy.mensagem); //obvio que não pode ShowMessage(´Mensagem 1: ´ + mensagem1.mensagem); ShowMessage(´Mensagem 2: ´ + mensagem2.mensagem); end;
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)