There is a lot of talking about the usage of FreeAndNil in destructors. I’ve never thought about it before so I used it quite often even in destructors. Although I don’t use it as a universal remedy function, it still seems to be a bad design: a thought shared by many leading Delphi experts. Thus I refactored the destructors in JWSCL to accompany them.
I introduced a function similar to FreeAndNil
procedure JwFree(var Obj);
It just frees an object…in the release build of an application. However, in a debug build it additionally sets the value of obj to $C which isn’t a valid memory address. So “Assigned” won’t work here.
Any access to this “freed” member will generate an AccessViolation at address $0000000C. So you will know that a member of JWSCL was used beyond its life time.
procedure JwFree(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
{$IFDEF DEBUG}
Pointer(Obj) := Pointer($C);
{$ENDIF DEBUG}
Temp.Free;
end;
I wonder if it should be extended to support different flavors like
They could be set by a compiler switch. Still have to think about this though…
What do you think?
I have commited these changes into the developer branch. They will be published in a next release so the current release won’t break a bad design.
6 Responses
Patrick van Logchem
25|Feb|2010 1I would argue for an odd value, because $C looks a lot like a valid memory-offset reached from a nil-pointer – Odd offsets are much less likely to appear, so they stand our better. Just a thought.
Bug
25|Feb|2010 2> because $C looks a lot like a valid memory-offset
> reached from a nil-pointer
We’ve got 32bit systems, so there is enough space for pointer values like:
$ABADC0DE
$BADC0DE
Some other ideas here:
http://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_debug_values
Oliver
25|Feb|2010 3Only that $ABADC0DE and $BADC0DE may be valid addresses on Windows, while the lower 64 KiB are always marked as guard pages (for the null pointer accesses).
The address must be below 0×10000 or above 0×80000000 for 32bit user mode code in Windows. And the latter one will be dodgy in some cases, because the shared address space above 0×80000000 *may* contain valid code as well …
Oliver
25|Feb|2010 4Correction $BADC0DE can be valid, $ABADC0DE is obviously above 0×80000000 and therefore *shouldn’t* be valid normally. But it’s dodgy nevertheless. Use VirtualAlloc and VirtualProtect and set up a guard page instead … or a page that always yields STATUS_ACCESS_DENIED.
JWSCL and FreeAndNil Second Attempt by JEDI Windows API
25|Feb|2010 5[...] my last article “Jwscl and FreeAndNil” there were some great comments on the source design. Oliver told me to use a guarded memory [...]
Patrick van Logchem
26|Feb|2010 6Funny, how most of those Magic debug values are still even numbers.
I suggested an odd (aka not-even!) number, because lots of code accessing pointers, is reading or writing to 4-byte aligned members.
Also, because the first 64 KiB is already there to act as a guard page for nil-based pointer accesses, I would suggest to use a value like $0000DEAD or some other recognizable address high into the first 64 KiB range.
I see no need to allocate a whole new page for that!
Leave a reply
You must be logged in to post a comment.
Search
Paypal donation (EUR)
Download Win 7 Search Provider
Categories
Archives
Tags
Recent Posts
Recent Comments
Blogroll
JEDI Sites
Pages
A design creation of Design Disease
Copyright © 2007 - JEDI Windows API - is proudly powered by WordPress
InSense 1.0 Theme by Design Disease brought to you by HostGator Web Hosting.