Forum > General
TObject.Free can cause SIGSEGV
dfeher:
Hello!
Some misplaced inherited Free; command in a class' destructor caused several hours of bug tracking for me. I had SIGSEGV when freeing some classes without an ancestor (so ancestor was TObject). I think the TObject.Free procedure should have been run when calling inherited Free, without any errors but then I saw the code below. It's from objpas.inc:
--- Code: --- procedure TObject.Free;
begin
// the call via self avoids a warning
if self<>nil then
self.destroy;
end;
--- End code ---
I've noticed the self<>nil. I think it should be better to use assigned(self) instead.
Am I right and this have to be reported as a bug or am I wrong?
eny:
Why would you want to override TObject.Free?
Can't you do the housecleaning in your classes' destructor?
Free is particularly useful if you reuse object variables that might have been freed before.
For that reason you can use the procedure FreeAndNil.
dfeher:
My class' destructor implementation looks like this:
--- Code: ---destructor TMyClass.Free;
begin
{ ...Some housecleaning... }
inherited Free;
end;
--- End code ---
So I didn't want to override TObject.Free just placed inherited Free in my destructor and I think it normally mustn't cause any errors.
eny:
Hm, that doesn't look like a good idea at all.
You're changing the default behaviour (as in 'expected') of the Free method.
And you're mixing two different freeing mechanisms.
What could happen is that when you call your own Free destructor, which is destroying the object, eventually calls the Free method, which in turn calls the Destroy destructor of the object you are already destroying.
Martin_fr:
--- Quote from: dfeher on April 14, 2010, 07:38:37 pm ---My class' destructor implementation looks like this:
--- Code: ---destructor TMyClass.Free;
begin
{ ...Some housecleaning... }
inherited Free;
end;
--- End code ---
So I didn't want to override TObject.Free just placed inherited Free in my destructor and I think it normally mustn't cause any errors.
--- End quote ---
So yes, this code must crash.
In TOBject Free is a procedure, not a destructor. But it does call a destructor.
In you code Free is a destructor, so when your Free has run, your onject gets destroyed. But it has been destroyed by Free in the meantime...
So at the end of your Free an already destroyed object is destroyed again.
If Free was a destructor, that would be ok => because calling an inherited destructor, within a destructor does not trigger a 2nd destruction.
Your code fails for the same reason as the following example (not tested)
Var // global
Foo: TFoo;
Destructor TFoo.Destroy;
begin
Foo.Destroy;
inherited; // optional / makes no differnece
end;
Procedure SomeElse;
begin
Foo.Destroy;
end;
Foo Destroy will be called twice.
Navigation
[0] Message Index
[#] Next page