This is the Emergence version of the code posted in the Aurora forums about counting the memory you've forgotten to delete. Refer to that topic for more information (link (http://www.ionicwind.com/forums/index.php/topic,1557.0.html)).
The main differences are that _dont_store_memory isn't needed because of the way linked lists are created, and you don't need to (and shouldn't) call free_global_list() because it is done automatically for you with ONEXIT.
declare import,GlobalAlloc(flags as uint,size as int),uint
declare import,GlobalFree(p as uint),uint
$define _ALLOC_TAG 0x19F30AD7
pointer alloclist
int _dont_store_memory
type _alloc_info
uint tag
pointer address
uint size
pointer listnode
end type
'' The following methods aren't meant for general use.
_asm
%define __NEW _mynew
%define __DELETE _mydelete
_endasm
global sub get_type_size( typ:int ),int
select typ
case @TYPESTRING
return 255
case @TYPEWSTRING
return 512
case @TYPECHAR
case& @TYPEUSER
return 1
case @TYPEWORD
return 2
case @TYPEDOUBLE
case& @TYPEINT64
return 8
end select
''default
return 4
end sub
global sub free_global_list( dt:pointer )
if alloclist <> 0 then
GlobalFree( alloclist )
alloclist = 0
end if
end sub
global sub add_global_pointer( info:pointer )
if alloclist = 0 then
alloclist = ListCreate( )
onexit( &free_global_list, 0 )
end if
ListAddHead( alloclist, info )
*<_alloc_info>info.listnode = ListGetFirst( alloclist )
end sub
global sub remove_global_pointer( node:pointer )
if alloclist = 0 then return
ListRemove( node )
end sub
global sub _mynew( typ:int, size:int ),uint
pointer info
settype info, _alloc_info
size *= get_type_size( typ & 0xFF )
if _dont_store_memory = 0 then _
size += len( _alloc_info )
info = GlobalAlloc( 0x40, size )
if _dont_store_memory <> 0 then _
return info
*info.tag = _ALLOC_TAG
*info.size = size - len( _alloc_info )
*info.address = info + len( _alloc_info )
add_global_pointer( info )
return *info.address
end sub
global sub _mydelete( p:pointer )
if p < len( _alloc_info ) then _
return
p -= len( _alloc_info )
if *<_alloc_info>p.tag <> _ALLOC_TAG then
print "Delete error - invalid pointer"
return
end if
remove_global_pointer( *<_alloc_info>p.listnode )
GlobalFree( p )
end sub
'' Feel free to use these methods.
global sub FreeLostMemory( )
pointer info : info = 0
settype info, _alloc_info
pointer n, temp
if alloclist = 0 then _
return
n = ListGetFirst( alloclist )
while n <> 0
info = ListGetData( n )
GlobalFree( info )
temp = n
n = ListGetNext( n )
ListRemove( temp )
wend
end sub
global sub DumpUnfreedMemory( )
pointer info : info = 0
int count : count = 0
if alloclist = 0 then
print "No memory recorded."
return
end if
print "\n--- Listing undeleted memory ---\n"
for info = each alloclist as _alloc_info
print "Address: 0x", hex$( *info.address ), "; Size (bytes): ", *info.size
count++
next
print "--- Found ", count, " unfreed memory addresses ---"
end sub
'' Test
type Type12Bytes
int x, y, z
end type
'' main
pointer x, y, t12
settype x, int
settype y, char
settype t12, Type12Bytes
x = new( int, 1 )
y = new( char, 1 )
t12 = new( Type12Bytes, 1 )
DumpUnfreedMemory( )
delete x
delete t12
DumpUnfreedMemory( )
FreeLostMemory( )
DumpUnfreedMemory( )
print "Done."
do:until inkey$<>""