Fórum Invalid Pointer Operation ao tentar liberar um objeto #423677
15/09/2012
0
este objeto implementa uma interface, e ao finalizar o processo tento liberar este objeto da memoria e da este erro
alguém sabe me dizer como faço pra resolver isso?
obrigado.
Rafael Reis
Curtir tópico
+ 0Posts
17/09/2012
Marco Salles
So que usar freeandnil para ambos .. Em algumas das vezes o free tb é suficiente
Gostei + 0
18/09/2012
Alisson Santos
No caso ele não utilizar o Create(Self), sendo assim teria que utilizar o FreeAndNil.
Eu sempre aconselho a utilizar esse comando, pois terá a certeza que o objeto está destruido e limpo a memória.
Gostei + 0
18/09/2012
Marco Salles
No caso ele não utilizar o Create(Self), sendo assim teria que utilizar o FreeAndNil.
Eu sempre aconselho a utilizar esse comando, pois terá a certeza que o objeto está destruido e limpo a memória.
Ponteiro é apenas algo que aponta para um endereço da memória . Neste endereço pode ter algo aproveitavel ou pode ter lixo
Quando vc utiliza o Freeandnil , vc ao "testar" o ponteiro , vc consegue identificar que este ponteiro aponta para
um endereço inexistente . Mas quem libera Recursos , quem libera memória definitivamente é o Free
faça um simples teste
coloque a instrução ReportMemoryLeaksOnShutdown:=true; no dpr para gerenciar a memória
coloque tres botões e execute separadamente o seguinte evento onclick
coloque
procedure TForm1.Button1Click(Sender: TObject); var lista:TStrings; i:integer; begin for i:=0 to 10 do begin lista:=TStringList.Create; Lista.free; end; end;
procedure TForm1.Button2Click(Sender: TObject); var lista:TStrings; i:integer; begin for i:=0 to 10 do begin lista:=TStringList.Create; FreeAndNil(lista); end; end;
//Aqui sim tem Vazamento de memória
procedure TForm1.Button3Click(Sender: TObject); var lista:TStrings; i:integer; begin for i:=0 to 10 do begin lista:=TStringList.Create; end; end;
Gostei + 0
18/09/2012
Alisson Santos
O free realmente faz a limpeza, mais ele não elimina o ponteiro.
Gostei + 0
18/09/2012
Deivison Melo
Gostei + 0
18/09/2012
Marco Salles
O free realmente faz a limpeza, mais ele não elimina o ponteiro.
Olha so , isto não é o caso e nem um pouco tão mais importante . o importante é o free
vou te dar um exemplo
var
lista:TStrings;
i:integer;
begin
if lista = nil then
showmessage('Mas Eu não estou utilizando o FreeanNil ???'+sLineBreak+
'Porque este Ponteiro Não foi Limpo ?????');
lista:=TStringList.Create;
FreeAndNil(lista);
end;Gostei + 0
18/09/2012
Alisson Santos
Gostei + 0
18/09/2012
Alisson Santos
Gostei + 0
18/09/2012
Marco Salles
veja esta situação
//variavel local fora do evento.. Ok ??
var
Lista:Tstrings;
dentro de um botão
if lista = nil then // tem que cria-la
lista:=TstringList.create;
//Vamos utiliza-la
lista.add('Na segunda Vez vai dar ponteiro Inválido');
showmessage(Lista.Strings[0]);
Lista.free;
end;
Tai um exemplo que devemos utilizar freeandNil ... Não para liberar Recuros , mas para instanciar o objeto , porque
do jeito que esta o Ponteiro vai apontar para um endereço que contem Lixo
depois oara entender o propósito , faça o mesmo teste utilizando o FreeandNil
if lista = nil then // tem que cria-la
lista:=TstringList.create;
//Vamos utiliza-la
lista.add('Na segunda Vez vai dar ponteiro Inválido');
showmessage(Lista.Strings[0]);
Lista.free;
end;
[]sds
Gostei + 0
18/09/2012
Rafael Reis
pra mim ficou bem claro.
até a próxima
Gostei + 0
25/09/2012
Rafael Reis
Eu estou criando um componente, onde o mesmo tem uma propriedade chamada DataSource que é do tipo TList, onde eu passo uma lista de qualquer objeto, e eu o populo lendo esta lista de objeto
sabem me dizer por qual motivo eu não consigo destruir esta lista quando eu destruo o componente? se eu tento destruir o componente, da erro de invalid pointer, se eu não destruo quando fecho a aplicação dá o mesmo erro. Abaixo segue o código fonte do componete.
acho que ainda não entendi muito bem como o delphi trabalha com essa questão de referência de memória.
Se puderem me ajudar mais uma vez, ficarei grato. Obrigado.
unit RCheckListBox;
interface
uses
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Vcl.CheckLst, Generics.Collections, RTTI;
type
TRCheckListBox = class(TCheckListBox)
private
FDescriptionName: String;
FMandatoryField: boolean;
FDataSource: TList;
FPersistentField: boolean;
FFieldName: String;
FIDName: String;
FListValue: TStrings;
function GetValue: String;
procedure SetDataSource(const Value: TList);
procedure SetDescriptionName(const Value: String);
procedure SetFieldName(const Value: String);
procedure SetIDName(const Value: String);
procedure SetMandatoryField(const Value: boolean);
procedure SetPersistentField(const Value: boolean);
procedure SetValue(const Value: String);
procedure SetListValue(const Value: TStrings);
{ Private declarations }
protected
{ Protected declarations }
published
property FieldName:String read FFieldName write SetFieldName;
property MandatoryField: boolean read FMandatoryField write SetMandatoryField;
property PersistentField: boolean read FPersistentField write SetPersistentField;
property IDFieldName:String read FIDName write SetIDName;
property DescriptionFieldName:String read FDescriptionName write SetDescriptionName;
property ListValue: TStrings read FListValue write SetListValue;
public
property DataSource:TList read FDataSource write SetDataSource;
property Value:String read GetValue write SetValue;
procedure FindIndexByIDFieldName(idFieldNameValue: string);
procedure DataBind;
function GetObject<T: class>:T;
function GetCheckedObjects: TList;
constructor Create(AOwner: TComponent);override;
destructor destroy;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('SIATD', [TRCheckListBox]);
end;
{ TRCheckListBox }
constructor TRCheckListBox.Create(AOwner: TComponent);
begin
inherited;
self.FListValue := TStringList.Create;
end;
procedure TRCheckListBox.DataBind;
var
i:integer;
context: TRttiContext;
prop: TRttiProperty;
begin
self.Clear;
if (self.FDataSource <> nil) or (self.FListValue <> nil) then
begin
if self.FDataSource <> nil then
begin
for i := 0 to self.FDataSource.Count-1 do
begin
prop := context.GetType(TObject(self.FDataSource[i]).ClassType).GetProperty(self.FDescriptionName);
self.Items.Add(prop.GetValue(TObject(self.FDataSource[i])).ToString);
end;
end
else
if self.FListValue <> nil then
begin
for I := 0 to self.FListValue.Count-1 do
begin
self.Items.Add(self.FListValue.Names[I])
end;
end;
if self.Items.Count > 0 then self.ItemIndex := 0;
end;
end;
destructor TRCheckListBox.destroy;
var
i:integer;
begin
for I := 0 to FDataSource.Count-1 do ////...>>>> aqui que dá o erro
FreeAndNil(TObject(FDataSource[i]))
FreeAndNil(FDataSource);
inherited Destroy;
end;
procedure TRCheckListBox.FindIndexByIDFieldName(idFieldNameValue: string);
var
I:integer;
context: TRttiContext;
prop: TRttiProperty;
begin
if Assigned(FDataSource) then
begin
for i := 0 to FDataSource.Count-1 do
begin
prop := context.GetType(TObject(FDataSource[i]).ClassType).GetProperty(self.IDFieldName);
if Pos(prop.GetValue(TObject(FDataSource[i])).ToString, idFieldNameValue ) > 0 then
Self.Checked[I] := true
else
Self.Checked[I] := false;
end;
end
else
begin
for I := 0 to self.Items.Count-1 do
begin
if FListValue.Count > 0 then
begin
if Pos(self.FListValue.ValueFromIndex[I], idFieldNameValue ) > 0 then
Self.Checked[I] := true
else
Self.Checked[I] := false;
end
else
begin
if Pos(self.Items[I], idFieldNameValue ) > 0 then
Self.Checked[I] := true
else
Self.Checked[I] := false;
end;
end;
end;
end;
function TRCheckListBox.GetCheckedObjects: TList;
var
i:integer;
list:Tlist;
begin
if FDataSource <> nil then
begin
list := TList.Create;
for i := 0 to FDataSource.Count-1 do
begin
if self.Checked[I] then
list.Add(TObject(DataSource[i]));
end;
result := list;
end else result := nil;
end;
function TRCheckListBox.GetObject<T>: T;
begin
if (FDataSource <> nil) and (self.Checked[self.GetItemIndex]) then
Result := T(TObject(FDataSource[self.GetItemIndex]));
end;
function TRCheckListBox.GetValue: String;
var
ind:integer;
context: TRttiContext;
prop: TRttiProperty;
val: string;
I: Integer;
begin
val := EmptyStr;
if Self.FDataSource = nil then
begin
for I := 0 to self.Items.Count-1 do
begin
if self.Checked[I] then
begin
if self.FListValue.Count = 0 then
val := val + self.Items[i]+','
else
val := val + self.FListValue.ValueFromIndex[I]+',';
end;
end;
System.Delete(val,System.Length(val),1);
result := val;
end
else
begin
for I := 0 to self.FDataSource.Count-1 do
begin
if self.Checked[I] then
begin
prop := context.GetType(TObject(Self.FDataSource[I]).ClassType).GetProperty(self.IDFieldName);
val := val + prop.GetValue(TObject(Self.FDataSource[I])).ToString+',';
end;
end;
System.Delete(val,System.Length(val),1);
result := val;
end;
end;
procedure TRCheckListBox.SetDataSource(const Value: TList);
begin
FDataSource := Value;
end;
procedure TRCheckListBox.SetDescriptionName(const Value: String);
begin
if FDescriptionName <> Value then
FDescriptionName := Value;
end;
procedure TRCheckListBox.SetFieldName(const Value: String);
begin
if FFieldName <> Value then
FFieldName := Value;
end;
procedure TRCheckListBox.SetIDName(const Value: String);
begin
if FIDName <> Value then
FIDName := Value;
end;
procedure TRCheckListBox.SetListValue(const Value: TStrings);
begin
if FListValue <> Value then
FListValue.Assign(Value);
end;
procedure TRCheckListBox.SetMandatoryField(const Value: boolean);
begin
if FMandatoryField <> Value then
FMandatoryField := Value;
end;
procedure TRCheckListBox.SetPersistentField(const Value: boolean);
begin
if FPersistentField <> Value then
FPersistentField := Value;
end;
procedure TRCheckListBox.SetValue(const Value: String);
begin
self.FindIndexByIDFieldName(Value);
end;
end.
Gostei + 0
25/09/2012
Alisson Santos
Gostei + 0
25/09/2012
Rafael Reis
então dá este erro de invalid Pointer Operation.
e se eu comento esta parte, o erro ocorre quando eu fecho a aplicação. Conseguir ser claro?
Gostei + 0
27/09/2012
Rafael Reis
Gostei + 0
27/09/2012
Rafael Reis
Qual seria a melhor forma de se fazer isso no Delphi?
Por exemplo
eu crio uma lista
lista := Tlist.create;
e passo para um outro form essa lista por referencia
ou seja, form2.lista := lista
ai na hora de destruir ele se perde.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)